Skip to content

Commit deac453

Browse files
committed
drm/i915: Fix glk+ degamma LUT conversions
The current implementation of change_lut_val_precision() is just a convoluted way of shifting by 8. Implement the proper rounding by just using drm_color_lut_extract() and intel_color_lut_pack() like everyone else does. And as the uapi can't handle >=1.0 values but the hardware can we need to clamp the results appropriately in the readout path. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231013131402.24072-5-ville.syrjala@linux.intel.com Reviewed-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com>
1 parent 5d76c81 commit deac453

1 file changed

Lines changed: 28 additions & 26 deletions

File tree

drivers/gpu/drm/i915/display/intel_color.c

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,14 +1526,27 @@ static int glk_degamma_lut_size(struct drm_i915_private *i915)
15261526
return 35;
15271527
}
15281528

1529-
/*
1530-
* change_lut_val_precision: helper function to upscale or downscale lut values.
1531-
* Parameters 'to' and 'from' needs to be less than 32. This should be sufficient
1532-
* as currently there are no lut values exceeding 32 bit.
1533-
*/
1534-
static u32 change_lut_val_precision(u32 lut_val, int to, int from)
1529+
static u32 glk_degamma_lut(const struct drm_color_lut *color)
1530+
{
1531+
return color->green;
1532+
}
1533+
1534+
static void glk_degamma_lut_pack(struct drm_color_lut *entry, u32 val)
1535+
{
1536+
/* PRE_CSC_GAMC_DATA is 3.16, clamp to 0.16 */
1537+
entry->red = entry->green = entry->blue = min(val, 0xffffu);
1538+
}
1539+
1540+
static u32 mtl_degamma_lut(const struct drm_color_lut *color)
1541+
{
1542+
return drm_color_lut_extract(color->green, 24);
1543+
}
1544+
1545+
static void mtl_degamma_lut_pack(struct drm_color_lut *entry, u32 val)
15351546
{
1536-
return mul_u32_u32(lut_val, (1 << to)) / (1 << from);
1547+
/* PRE_CSC_GAMC_DATA is 3.24, clamp to 0.16 */
1548+
entry->red = entry->green = entry->blue =
1549+
intel_color_lut_pack(min(val, 0xffffffu), 24);
15371550
}
15381551

15391552
static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state,
@@ -1570,20 +1583,16 @@ static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state,
15701583
* ToDo: Extend to max 7.0. Enable 32 bit input value
15711584
* as compared to just 16 to achieve this.
15721585
*/
1573-
u32 lut_val;
1574-
1575-
if (DISPLAY_VER(i915) >= 14)
1576-
lut_val = change_lut_val_precision(lut[i].green, 24, 16);
1577-
else
1578-
lut_val = lut[i].green;
1579-
15801586
ilk_lut_write(crtc_state, PRE_CSC_GAMC_DATA(pipe),
1581-
lut_val);
1587+
DISPLAY_VER(i915) >= 14 ?
1588+
mtl_degamma_lut(&lut[i]) : glk_degamma_lut(&lut[i]));
15821589
}
15831590

15841591
/* Clamp values > 1.0. */
15851592
while (i++ < glk_degamma_lut_size(i915))
1586-
ilk_lut_write(crtc_state, PRE_CSC_GAMC_DATA(pipe), 1 << 16);
1593+
ilk_lut_write(crtc_state, PRE_CSC_GAMC_DATA(pipe),
1594+
DISPLAY_VER(i915) >= 14 ?
1595+
1 << 24 : 1 << 16);
15871596

15881597
ilk_lut_write(crtc_state, PRE_CSC_GAMC_INDEX(pipe), 0);
15891598
}
@@ -3570,17 +3579,10 @@ static struct drm_property_blob *glk_read_degamma_lut(struct intel_crtc *crtc)
35703579
for (i = 0; i < lut_size; i++) {
35713580
u32 val = intel_de_read_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe));
35723581

3573-
/*
3574-
* For MTL and beyond, convert back the 24 bit lut values
3575-
* read from HW to 16 bit values to maintain parity with
3576-
* userspace values
3577-
*/
35783582
if (DISPLAY_VER(dev_priv) >= 14)
3579-
val = change_lut_val_precision(val, 16, 24);
3580-
3581-
lut[i].red = val;
3582-
lut[i].green = val;
3583-
lut[i].blue = val;
3583+
mtl_degamma_lut_pack(&lut[i], val);
3584+
else
3585+
glk_degamma_lut_pack(&lut[i], val);
35843586
}
35853587

35863588
intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),

0 commit comments

Comments
 (0)