drm/i915: Expose full 1024 LUT entries on ivb+
On ivb+ we can select between the regular 10bit LUT mode with 1024 entries, and the split mode where the LUT is split into seprate degamma and gamma halves (each with 512 entries). Currently we expose the split gamma size of 512 as the GAMMA/DEGAMMA_LUT_SIZE. When using only degamma or gamma (not both) we are wasting half of the hardware LUT entries. Let's flip that around so that we expose the full 1024 entries and just throw away half of the user provided entries when using the split gamma mode. Cc: Matt Roper <matthew.d.roper@intel.com> Suggested-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190401200231.2333-8-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar <uma.shankar@intel.com>
This commit is contained in:
parent
821062478c
commit
795f672b88
|
@ -125,7 +125,7 @@
|
|||
#define ILK_COLORS \
|
||||
.color = { .gamma_lut_size = 1024 }
|
||||
#define IVB_COLORS \
|
||||
.color = { .degamma_lut_size = 512, .gamma_lut_size = 512 }
|
||||
.color = { .degamma_lut_size = 1024, .gamma_lut_size = 1024 }
|
||||
#define CHV_COLORS \
|
||||
.color = { .degamma_lut_size = 65, .gamma_lut_size = 257, \
|
||||
.degamma_lut_tests = DRM_COLOR_LUT_NON_DECREASING, \
|
||||
|
|
|
@ -538,6 +538,14 @@ static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
|
|||
ilk_load_lut_10(crtc, gamma_lut);
|
||||
}
|
||||
|
||||
static int ivb_lut_10_size(u32 prec_index)
|
||||
{
|
||||
if (prec_index & PAL_PREC_SPLIT_MODE)
|
||||
return 512;
|
||||
else
|
||||
return 1024;
|
||||
}
|
||||
|
||||
/*
|
||||
* IVB/HSW Bspec / PAL_PREC_INDEX:
|
||||
* "Restriction : Index auto increment mode is not
|
||||
|
@ -545,31 +553,21 @@ static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
|
|||
*/
|
||||
static void ivb_load_lut_10(struct intel_crtc *crtc,
|
||||
const struct drm_property_blob *blob,
|
||||
u32 prec_index, bool duplicate)
|
||||
u32 prec_index)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
int hw_lut_size = ivb_lut_10_size(prec_index);
|
||||
const struct drm_color_lut *lut = blob->data;
|
||||
int i, lut_size = drm_color_lut_size(blob);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
||||
/*
|
||||
* We advertise the split gamma sizes. When not using split
|
||||
* gamma we just duplicate each entry.
|
||||
*
|
||||
* TODO: expose the full LUT to userspace
|
||||
*/
|
||||
if (duplicate) {
|
||||
for (i = 0; i < lut_size; i++) {
|
||||
I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++);
|
||||
I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i]));
|
||||
I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++);
|
||||
I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i]));
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < lut_size; i++) {
|
||||
I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++);
|
||||
I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i]));
|
||||
}
|
||||
for (i = 0; i < hw_lut_size; i++) {
|
||||
/* We discard half the user entries in split gamma mode */
|
||||
const struct drm_color_lut *entry =
|
||||
&lut[i * (lut_size - 1) / (hw_lut_size - 1)];
|
||||
|
||||
I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++);
|
||||
I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -582,9 +580,10 @@ static void ivb_load_lut_10(struct intel_crtc *crtc,
|
|||
/* On BDW+ the index auto increment mode actually works */
|
||||
static void bdw_load_lut_10(struct intel_crtc *crtc,
|
||||
const struct drm_property_blob *blob,
|
||||
u32 prec_index, bool duplicate)
|
||||
u32 prec_index)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
|
||||
int hw_lut_size = ivb_lut_10_size(prec_index);
|
||||
const struct drm_color_lut *lut = blob->data;
|
||||
int i, lut_size = drm_color_lut_size(blob);
|
||||
enum pipe pipe = crtc->pipe;
|
||||
|
@ -592,20 +591,12 @@ static void bdw_load_lut_10(struct intel_crtc *crtc,
|
|||
I915_WRITE(PREC_PAL_INDEX(pipe), prec_index |
|
||||
PAL_PREC_AUTO_INCREMENT);
|
||||
|
||||
/*
|
||||
* We advertise the split gamma sizes. When not using split
|
||||
* gamma we just duplicate each entry.
|
||||
*
|
||||
* TODO: expose the full LUT to userspace
|
||||
*/
|
||||
if (duplicate) {
|
||||
for (i = 0; i < lut_size; i++) {
|
||||
I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i]));
|
||||
I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i]));
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < lut_size; i++)
|
||||
I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(&lut[i]));
|
||||
for (i = 0; i < hw_lut_size; i++) {
|
||||
/* We discard half the user entries in split gamma mode */
|
||||
const struct drm_color_lut *entry =
|
||||
&lut[i * (lut_size - 1) / (hw_lut_size - 1)];
|
||||
|
||||
I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -647,15 +638,15 @@ static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
|
|||
i9xx_load_luts(crtc_state);
|
||||
} else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
|
||||
ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
|
||||
PAL_PREC_INDEX_VALUE(0), false);
|
||||
PAL_PREC_INDEX_VALUE(0));
|
||||
ivb_load_lut_10_max(crtc);
|
||||
ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
|
||||
PAL_PREC_INDEX_VALUE(512), false);
|
||||
PAL_PREC_INDEX_VALUE(512));
|
||||
} else {
|
||||
const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
|
||||
|
||||
ivb_load_lut_10(crtc, blob,
|
||||
PAL_PREC_INDEX_VALUE(0), true);
|
||||
PAL_PREC_INDEX_VALUE(0));
|
||||
ivb_load_lut_10_max(crtc);
|
||||
}
|
||||
}
|
||||
|
@ -670,15 +661,15 @@ static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
|
|||
i9xx_load_luts(crtc_state);
|
||||
} else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
|
||||
bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
|
||||
PAL_PREC_INDEX_VALUE(0), false);
|
||||
PAL_PREC_INDEX_VALUE(0));
|
||||
ivb_load_lut_10_max(crtc);
|
||||
bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
|
||||
PAL_PREC_INDEX_VALUE(512), false);
|
||||
PAL_PREC_INDEX_VALUE(512));
|
||||
} else {
|
||||
const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
|
||||
|
||||
bdw_load_lut_10(crtc, blob,
|
||||
PAL_PREC_INDEX_VALUE(0), true);
|
||||
PAL_PREC_INDEX_VALUE(0));
|
||||
ivb_load_lut_10_max(crtc);
|
||||
}
|
||||
}
|
||||
|
@ -770,7 +761,7 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state)
|
|||
if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
|
||||
i9xx_load_luts(crtc_state);
|
||||
} else {
|
||||
bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0), false);
|
||||
bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
|
||||
ivb_load_lut_10_max(crtc);
|
||||
}
|
||||
}
|
||||
|
@ -787,7 +778,7 @@ static void icl_load_luts(const struct intel_crtc_state *crtc_state)
|
|||
GAMMA_MODE_MODE_8BIT) {
|
||||
i9xx_load_luts(crtc_state);
|
||||
} else {
|
||||
bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0), false);
|
||||
bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
|
||||
ivb_load_lut_10_max(crtc);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue