Commit db9c06df authored by Johnson Lin's avatar Johnson Lin Committed by Ville Syrjälä

drm/i915: Fix Limited Range Color Handling

Some panels support limited range output (16-235) compared
to full range RGB values (0-255). Also userspace can control
the RGB range using "Broadcast RGB" property. Currently the
code to handle full range to limited range is broken. This
patch fixes the same by properly scaling down all the full
range co-efficients with limited range scaling factor.

v2: Fixed Ville's review comments.

v3: Changed input to const and used correct data types as
    suggested by Ville

v4: Fixed some missing data type corrections.
Signed-off-by: default avatarJohnson Lin <johnson.lin@intel.com>
Signed-off-by: default avatarUma Shankar <uma.shankar@intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1517327489-26128-1-git-send-email-uma.shankar@intel.com
parent 4552f50a
...@@ -84,26 +84,25 @@ static bool crtc_state_is_legacy_gamma(struct drm_crtc_state *state) ...@@ -84,26 +84,25 @@ static bool crtc_state_is_legacy_gamma(struct drm_crtc_state *state)
/* /*
* When using limited range, multiply the matrix given by userspace by * When using limited range, multiply the matrix given by userspace by
* the matrix that we would use for the limited range. We do the * the matrix that we would use for the limited range.
* multiplication in U2.30 format.
*/ */
static void ctm_mult_by_limited(uint64_t *result, int64_t *input) static void ctm_mult_by_limited(u64 *result, const u64 *input)
{ {
int i; int i;
for (i = 0; i < 9; i++) for (i = 0; i < 9; i++) {
result[i] = 0; u64 user_coeff = input[i];
u32 limited_coeff = CTM_COEFF_LIMITED_RANGE;
u32 abs_coeff = clamp_val(CTM_COEFF_ABS(user_coeff), 0,
CTM_COEFF_4_0 - 1) >> 2;
for (i = 0; i < 3; i++) { /*
int64_t user_coeff = input[i * 3 + i]; * By scaling every co-efficient with limited range (16-235)
uint64_t limited_coeff = CTM_COEFF_LIMITED_RANGE >> 2; * vs full range (0-255) the final o/p will be scaled down to
uint64_t abs_coeff = clamp_val(CTM_COEFF_ABS(user_coeff), * fit in the limited range supported by the panel.
0, */
CTM_COEFF_4_0 - 1) >> 2; result[i] = mul_u32_u32(limited_coeff, abs_coeff) >> 30;
result[i] |= user_coeff & CTM_COEFF_SIGN;
result[i * 3 + i] = (limited_coeff * abs_coeff) >> 27;
if (CTM_COEFF_NEGATIVE(user_coeff))
result[i * 3 + i] |= CTM_COEFF_SIGN;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment