[Intel-gfx] [RFC v1 6/7] drm/i915/icl: Add support for multi segmented gamma mode
Uma Shankar
uma.shankar at intel.com
Tue Mar 19 08:30:17 UTC 2019
Gen11 introduced a new gamma mode i.e, multi segmented
gamma mode. Added support for the same.
Signed-off-by: Uma Shankar <uma.shankar at intel.com>
---
drivers/gpu/drm/i915/intel_color.c | 105 +++++++++++++++++++++++++++++++------
1 file changed, 90 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c
index 399d63d..7733c256 100644
--- a/drivers/gpu/drm/i915/intel_color.c
+++ b/drivers/gpu/drm/i915/intel_color.c
@@ -105,6 +105,9 @@
MULTI_SEGMENTED_GAMMA_MODE_12BIT | \
BIT_SPLIT_GAMMA_MODE_12BIT)
+#define GEN11_GET_MS10BITS_OF_LUT(lut) (((lut) >> 6) & 0x3FF)
+#define GEN11_GET_LS6BITS_OF_LUT(lut) ((lut) & 0x3F)
+
static bool lut_is_legacy(const struct drm_property_blob *lut)
{
return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH;
@@ -538,6 +541,10 @@ static void bdw_load_degamma_lut(const struct intel_crtc_state *crtc_state)
if (degamma_lut) {
const struct drm_color_lut *lut = degamma_lut->data;
+ if (crtc_state->gamma_mode_type ==
+ MULTI_SEGMENTED_GAMMA_MODE_12BIT)
+ lut += 9;
+
for (i = 0; i < lut_size; i++) {
u32 word =
drm_color_lut_extract(lut[i].red, 10) << 20 |
@@ -563,6 +570,7 @@ static void bdw_load_gamma_lut(const struct intel_crtc_state *crtc_state, u32 of
const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
u32 i, lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
enum pipe pipe = crtc->pipe;
+ u32 word;
WARN_ON(offset & ~PAL_PREC_INDEX_VALUE_MASK);
@@ -574,13 +582,32 @@ static void bdw_load_gamma_lut(const struct intel_crtc_state *crtc_state, u32 of
if (gamma_lut) {
const struct drm_color_lut *lut = gamma_lut->data;
- for (i = 0; i < lut_size; i++) {
- u32 word =
- (drm_color_lut_extract(lut[i].red, 10) << 20) |
- (drm_color_lut_extract(lut[i].green, 10) << 10) |
- drm_color_lut_extract(lut[i].blue, 10);
-
- I915_WRITE(PREC_PAL_DATA(pipe), word);
+ if (crtc_state->gamma_mode_type ==
+ MULTI_SEGMENTED_GAMMA_MODE_12BIT) {
+ lut_size = 9 + 512;
+ for (i = 9; i < lut_size; i++) {
+ /* For Even Index */
+ word = (GEN11_GET_LS6BITS_OF_LUT(lut[i].red) << 20) |
+ (GEN11_GET_LS6BITS_OF_LUT(lut[i].green) << 10)|
+ GEN11_GET_LS6BITS_OF_LUT(lut[i].blue);
+
+ I915_WRITE(PREC_PAL_MULTI_SEG_DATA(pipe), word);
+
+ /* For ODD index */
+ word = (GEN11_GET_MS10BITS_OF_LUT(lut[i].red) << 20) |
+ (GEN11_GET_MS10BITS_OF_LUT(lut[i].green) << 10) |
+ GEN11_GET_MS10BITS_OF_LUT(lut[i].blue);
+
+ I915_WRITE(PREC_PAL_MULTI_SEG_DATA(pipe), word);
+ }
+ } else {
+ for (i = 0; i < lut_size; i++) {
+ word = (drm_color_lut_extract(lut[i].red, 10) << 20) |
+ (drm_color_lut_extract(lut[i].green, 10) << 10) |
+ drm_color_lut_extract(lut[i].blue, 10);
+
+ I915_WRITE(PREC_PAL_DATA(pipe), word);
+ }
}
/* Program the max register to clamp values > 1.0. */
@@ -685,15 +712,57 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state)
bdw_load_gamma_lut(crtc_state, 0);
}
+static void icl_load_gamma_multi_segmented_lut(const struct intel_crtc_state
+ *crtc_state, u32 offset)
+{
+ struct drm_crtc *crtc = crtc_state->base.crtc;
+ struct drm_device *dev = crtc_state->base.crtc->dev;
+ struct drm_i915_private *dev_priv = to_i915(dev);
+ enum pipe pipe = to_intel_crtc(crtc)->pipe;
+ u32 i, lut_size = 9;
+
+ WARN_ON(offset & ~PAL_PREC_MULTI_SEGMENT_INDEX_VALUE_MASK);
+
+ I915_WRITE(PREC_PAL_MULTI_SEG_INDEX(pipe),
+ (PAL_PREC_AUTO_INCREMENT | offset));
+
+ if (crtc_state->base.gamma_lut) {
+ struct drm_color_lut *lut =
+ (struct drm_color_lut *)crtc_state->base.gamma_lut->data;
+
+ for (i = 0; i < lut_size; i++) {
+ u32 word;
+
+ /* For Even Index */
+ word = (GEN11_GET_LS6BITS_OF_LUT(lut[i].red) << 20) |
+ (GEN11_GET_LS6BITS_OF_LUT(lut[i].green) << 10) |
+ GEN11_GET_LS6BITS_OF_LUT(lut[i].blue);
+ I915_WRITE(PREC_PAL_MULTI_SEG_DATA(pipe), word);
+
+ /* For ODD index */
+ word = (GEN11_GET_MS10BITS_OF_LUT(lut[i].red) << 20) |
+ (GEN11_GET_MS10BITS_OF_LUT(lut[i].green) << 10) |
+ GEN11_GET_MS10BITS_OF_LUT(lut[i].blue);
+ I915_WRITE(PREC_PAL_MULTI_SEG_DATA(pipe), word);
+ }
+ }
+
+ bdw_load_gamma_lut(crtc_state, 0);
+}
+
static void icl_load_luts(const struct intel_crtc_state *crtc_state)
{
glk_load_degamma_lut(crtc_state);
- if (crtc_state_is_legacy_gamma(crtc_state))
+ if (crtc_state_is_legacy_gamma(crtc_state)) {
i9xx_load_luts(crtc_state);
- else
+ } else if (crtc_state->gamma_mode_type ==
+ MULTI_SEGMENTED_GAMMA_MODE_12BIT) {
+ icl_load_gamma_multi_segmented_lut(crtc_state, 0);
+ } else {
/* ToDo: Add support for multi segment gamma LUT */
bdw_load_gamma_lut(crtc_state, 0);
+ }
}
static void cherryview_load_luts(const struct intel_crtc_state *crtc_state)
@@ -910,16 +979,22 @@ int intel_color_check(struct intel_crtc_state *crtc_state)
drm_color_lut_check(gamma_lut, gamma_tests))
return -EINVAL;
- if (INTEL_GEN(dev_priv) >= 11)
- crtc_state->gamma_mode = GAMMA_MODE_MODE_10BIT |
- PRE_CSC_GAMMA_ENABLE |
+ if (INTEL_GEN(dev_priv) >= 11) {
+ crtc_state->gamma_mode = PRE_CSC_GAMMA_ENABLE |
POST_CSC_GAMMA_ENABLE;
- else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
+ if (crtc_state->gamma_mode_type ==
+ MULTI_SEGMENTED_GAMMA_MODE_12BIT)
+ crtc_state->gamma_mode |=
+ GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED;
+ else
+ crtc_state->gamma_mode |= GAMMA_MODE_MODE_10BIT;
+ } else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
crtc_state->gamma_mode = GAMMA_MODE_MODE_10BIT;
- else if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
+ } else if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) {
crtc_state->gamma_mode = GAMMA_MODE_MODE_SPLIT;
- else
+ } else {
crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
+ }
if (INTEL_GEN(dev_priv) >= 11) {
if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
--
1.9.1
More information about the Intel-gfx
mailing list