On Thu, Dec 17, 2015 at 06:57:56PM +0000, Lionel Landwerlin wrote:
> From: Shashank Sharma <[email protected]>
> 
> Implement degamma, csc and gamma steps on CHV.
> 
> Signed-off-by: Shashank Sharma <[email protected]>
> Signed-off-by: Kausal Malladi <[email protected]>
> ---
>  drivers/gpu/drm/i915/Makefile              |   3 +-
>  drivers/gpu/drm/i915/i915_drv.c            |   5 +-
>  drivers/gpu/drm/i915/i915_drv.h            |   2 +
>  drivers/gpu/drm/i915/i915_reg.h            |  26 +++
>  drivers/gpu/drm/i915/intel_color_manager.c | 353 
> +++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_color_manager.h |  91 ++++++++
>  drivers/gpu/drm/i915/intel_display.c       |   2 +
>  drivers/gpu/drm/i915/intel_drv.h           |   4 +
>  8 files changed, 484 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/intel_color_manager.c
>  create mode 100644 drivers/gpu/drm/i915/intel_color_manager.h
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 0851de07..c66d56a 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -64,7 +64,8 @@ i915-y += intel_audio.o \
>         intel_overlay.o \
>         intel_psr.o \
>         intel_sideband.o \
> -       intel_sprite.o
> +       intel_sprite.o \
> +       intel_color_manager.o
>  i915-$(CONFIG_ACPI)          += intel_acpi.o intel_opregion.o
>  i915-$(CONFIG_DRM_FBDEV_EMULATION)   += intel_fbdev.o
>  
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 3ac616d..4396300 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -34,6 +34,7 @@
>  #include "i915_drv.h"
>  #include "i915_trace.h"
>  #include "intel_drv.h"
> +#include "intel_color_manager.h"
>  
>  #include <linux/console.h>
>  #include <linux/module.h>
> @@ -311,7 +312,9 @@ static const struct intel_device_info 
> intel_cherryview_info = {
>       .gen = 8, .num_pipes = 3,
>       .need_gfx_hws = 1, .has_hotplug = 1,
>       .ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
> -     .is_cherryview = 1,
> +     .is_valleyview = 1,
> +     .num_samples_after_ctm = CHV_10BIT_GAMMA_MAX_VALS,
> +     .num_samples_before_ctm = CHV_DEGAMMA_MAX_VALS,
>       .display_mmio_offset = VLV_DISPLAY_BASE,
>       GEN_CHV_PIPEOFFSETS,
>       CURSOR_OFFSETS,
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 1d28d90..4eb0fab 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -793,6 +793,8 @@ struct intel_device_info {
>       u8 num_sprites[I915_MAX_PIPES];
>       u8 gen;
>       u8 ring_mask; /* Rings supported by the HW */
> +     u16 num_samples_after_ctm;
> +     u16 num_samples_before_ctm;
>       DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON);
>       /* Register offsets for the various display pipes and transcoders */
>       int pipe_offsets[I915_MAX_TRANSCODERS];
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 007ae83..36bb320 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -8154,4 +8154,30 @@ enum skl_disp_power_wells {
>  #define GEN9_VEBOX_MOCS(i)   _MMIO(0xcb00 + (i) * 4) /* Video MOCS registers 
> */
>  #define GEN9_BLT_MOCS(i)     _MMIO(0xcc00 + (i) * 4) /* Blitter MOCS 
> registers */
>  
> +/* Color Management */
> +#define PIPEA_CGM_CONTROL                    (VLV_DISPLAY_BASE + 0x67A00)
> +#define PIPEB_CGM_CONTROL                    (VLV_DISPLAY_BASE + 0x69A00)
> +#define PIPEC_CGM_CONTROL                    (VLV_DISPLAY_BASE + 0x6BA00)
> +#define PIPEA_CGM_GAMMA                      (VLV_DISPLAY_BASE + 0x67000)
> +#define PIPEB_CGM_GAMMA                      (VLV_DISPLAY_BASE + 0x69000)
> +#define PIPEC_CGM_GAMMA                      (VLV_DISPLAY_BASE + 0x6B000)
> +#define _PIPE_CGM_CONTROL(pipe) \
> +     (_PIPE3(pipe, PIPEA_CGM_CONTROL, PIPEB_CGM_CONTROL, PIPEC_CGM_CONTROL))
> +#define _PIPE_GAMMA_BASE(pipe) \
> +     (_PIPE3(pipe, PIPEA_CGM_GAMMA, PIPEB_CGM_GAMMA, PIPEC_CGM_GAMMA))
> +
> +#define PIPEA_CGM_DEGAMMA                      (VLV_DISPLAY_BASE + 0x66000)
> +#define PIPEB_CGM_DEGAMMA                      (VLV_DISPLAY_BASE + 0x68000)
> +#define PIPEC_CGM_DEGAMMA                      (VLV_DISPLAY_BASE + 0x6A000)
> +#define _PIPE_DEGAMMA_BASE(pipe) \
> +     (_PIPE3(pipe, PIPEA_CGM_DEGAMMA, PIPEB_CGM_DEGAMMA, PIPEC_CGM_DEGAMMA))
> +
> +#define PIPEA_CGM_CSC                                (VLV_DISPLAY_BASE + 
> 0x67900)
> +#define PIPEB_CGM_CSC                                (VLV_DISPLAY_BASE + 
> 0x69900)
> +#define PIPEC_CGM_CSC                                (VLV_DISPLAY_BASE + 
> 0x6B900)
> +#define _PIPE_CSC_BASE(pipe) \
> +     (_PIPE3(pipe, PIPEA_CGM_CSC, PIPEB_CGM_CSC, PIPEC_CGM_CSC))
> +
> +
> +
>  #endif /* _I915_REG_H_ */
> diff --git a/drivers/gpu/drm/i915/intel_color_manager.c 
> b/drivers/gpu/drm/i915/intel_color_manager.c
> new file mode 100644
> index 0000000..02eee98
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/intel_color_manager.c
> @@ -0,0 +1,353 @@
> +/*
> + * Copyright © 2015 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
> DEALINGS
> + * IN THE SOFTWARE.
> + *
> + * Authors:
> + * Shashank Sharma <[email protected]>
> + * Kausal Malladi <[email protected]>
> + */
> +
> +#include "intel_color_manager.h"
> +
> +static u16 chv_prepare_csc_coeff(s64 csc_coeff)
> +{
> +     u16 csc_s3_12_format = 0;
> +     u16 csc_int_value;
> +     u16 csc_fract_value;
> +
> +     if (csc_coeff < 0)
> +             csc_s3_12_format = CSC_COEFF_SIGN;
> +     csc_coeff = abs(csc_coeff);
> +     csc_coeff += CHV_CSC_FRACT_ROUNDOFF;
> +     if (csc_coeff > CHV_CSC_COEFF_MAX + 1)
> +             csc_coeff = CHV_CSC_COEFF_MAX + 1;
> +     else if (csc_coeff > CHV_CSC_COEFF_MAX)
> +             csc_coeff = CHV_CSC_COEFF_MAX;
> +
> +     csc_int_value = csc_coeff >> CHV_CSC_COEFF_SHIFT;
> +     csc_int_value <<= CHV_CSC_COEFF_INT_SHIFT;
> +
> +     csc_fract_value = csc_coeff >> CHV_CSC_COEFF_FRACT_SHIFT;
> +
> +     csc_s3_12_format |= csc_int_value | csc_fract_value;
> +
> +     return csc_s3_12_format;
> +}
> +
> +static int chv_set_csc(struct drm_device *dev, struct drm_property_blob 
> *blob,
> +             struct drm_crtc *crtc)
> +{
> +     u16 temp;
> +     u32 word = 0;
> +     int count = 0;
> +     i915_reg_t val;
> +     struct drm_ctm *csc_data;
> +     struct drm_i915_private *dev_priv = dev->dev_private;
> +     enum pipe pipe;
> +
> +     if (WARN_ON(!blob))
> +             return -EINVAL;
> +
> +     if (blob->length != sizeof(struct drm_ctm)) {
> +             DRM_ERROR("Invalid length of data received\n");
> +             return -EINVAL;
> +     }
> +
> +     csc_data = (struct drm_ctm *)blob->data;
> +     pipe = to_intel_crtc(crtc)->pipe;
> +
> +     /* Disable CSC functionality */
> +     val = _MMIO(_PIPE_CGM_CONTROL(pipe));
> +     I915_WRITE(val, I915_READ(val) & (~CGM_CSC_EN));
> +
> +     DRM_DEBUG_DRIVER("Disabled CSC Functionality on Pipe %c\n",
> +                     pipe_name(pipe));
> +
> +     val = _MMIO(_PIPE_CSC_BASE(pipe));
> +
> +     /*
> +     * First 8 of 9 CSC correction values go in pair, to first
> +     * 4 CSC register (bit 0:15 and 16:31)
> +     */
> +     while (count < CSC_MAX_VALS - 1) {
> +             temp = chv_prepare_csc_coeff(
> +                                     csc_data->ctm_coeff[count]);
> +             SET_BITS(word, temp, 0, 16);
> +             count++;
> +
> +             temp = chv_prepare_csc_coeff(
> +                             csc_data->ctm_coeff[count]);
> +             SET_BITS(word, temp, 16, 16);
> +             count++;
> +
> +             I915_WRITE(val, word);
> +             val.reg += 4;
> +     }
> +
> +     /* 9th coeff goes to 5th register, bit 0:16 */
> +     temp = chv_prepare_csc_coeff(
> +                     csc_data->ctm_coeff[count]);
> +     SET_BITS(word, temp, 0, 16);
> +     I915_WRITE(val, word);
> +
> +     /* Enable CSC functionality */
> +     val = _MMIO(_PIPE_CGM_CONTROL(pipe));
> +     I915_WRITE(val, I915_READ(val) | CGM_CSC_EN);
> +     DRM_DEBUG_DRIVER("CSC enabled on Pipe %c\n", pipe_name(pipe));
> +     return 0;
> +}
> +
> +static int chv_set_degamma(struct drm_device *dev,
> +     struct drm_property_blob *blob, struct drm_crtc *crtc)
> +{
> +     u16 red_fract, green_fract, blue_fract;
> +     u32 red, green, blue;
> +     u32 num_samples;
> +     u32 word = 0;
> +     u32 count, cgm_control, cgm_degamma_reg;
> +     i915_reg_t val;
> +     enum pipe pipe;
> +     struct drm_palette *degamma_data;
> +     struct drm_i915_private *dev_priv = dev->dev_private;
> +     struct drm_r32g32b32 *correction_values = NULL;
> +     struct drm_crtc_state *state = crtc->state;
> +
> +     if (WARN_ON(!blob))
> +             return -EINVAL;
> +
> +     degamma_data = (struct drm_palette *)blob->data;
> +     pipe = to_intel_crtc(crtc)->pipe;
> +     num_samples = blob->length / sizeof(struct drm_r32g32b32);
> +
> +     switch (num_samples) {
> +     case GAMMA_DISABLE_VALS:

If we implement my suggestion for a num_samples helper, we could put the
NULL->0 samples logic into that one and nicely unify things. And probably
we should also reject a gamma table with size 0 as nonsens then.

> +             /* Disable DeGamma functionality on Pipe - CGM Block */
> +             val = _MMIO(_PIPE_CGM_CONTROL(pipe));
> +             cgm_control = I915_READ(val);
> +             cgm_control &= ~CGM_DEGAMMA_EN;
> +             state->palette_before_ctm_blob = NULL;
> +
> +             I915_WRITE(val, cgm_control);
> +             DRM_DEBUG_DRIVER("DeGamma disabled on Pipe %c\n",
> +                             pipe_name(pipe));
> +             break;
> +
> +     case CHV_DEGAMMA_MAX_VALS:
> +             cgm_degamma_reg = _PIPE_DEGAMMA_BASE(pipe);
> +             count = 0;
> +             correction_values = degamma_data->lut;
> +             while (count < CHV_DEGAMMA_MAX_VALS) {
> +                     blue = correction_values[count].b32;
> +                     green = correction_values[count].g32;
> +                     red = correction_values[count].r32;
> +
> +                     if (blue > CHV_MAX_GAMMA)
> +                             blue = CHV_MAX_GAMMA;
> +
> +                     if (green > CHV_MAX_GAMMA)
> +                             green = CHV_MAX_GAMMA;
> +
> +                     if (red > CHV_MAX_GAMMA)
> +                             red = CHV_MAX_GAMMA;
> +
> +                     blue_fract = GET_BITS(blue, 10, 14);
> +                     green_fract = GET_BITS(green, 10, 14);
> +                     red_fract = GET_BITS(red, 10, 14);
> +
> +                     /* Green (29:16) and Blue (13:0) in DWORD1 */
> +                     SET_BITS(word, green_fract, 16, 14);
> +                     SET_BITS(word, blue_fract, 0, 14);
> +                     val = _MMIO(cgm_degamma_reg);
> +                     I915_WRITE(val, word);
> +                     cgm_degamma_reg += 4;
> +
> +                     /* Red (13:0) to be written to DWORD2 */
> +                     word = red_fract;
> +                     val = _MMIO(cgm_degamma_reg);
> +                     I915_WRITE(val, word);
> +                     cgm_degamma_reg += 4;
> +                     count++;
> +             }
> +
> +             DRM_DEBUG_DRIVER("DeGamma LUT loaded for Pipe %c\n",
> +                             pipe_name(pipe));
> +
> +             /* Enable DeGamma on Pipe */
> +             val = _MMIO(_PIPE_CGM_CONTROL(pipe));
> +             I915_WRITE(val, I915_READ(val) | CGM_DEGAMMA_EN);
> +             DRM_DEBUG_DRIVER("DeGamma correction enabled on Pipe %c\n",
> +                             pipe_name(pipe));
> +             break;
> +
> +     default:
> +             DRM_ERROR("Invalid number of samples for DeGamma LUT\n");
> +             return -EINVAL;

This is a relict from pre-atomic and won't work anymore: There's no way to
pass error code from _commit functions up to userspace, and there's also
no way to abort an atomic commit at that stage. Input validation must
happen in atomic_check callbacks (or compute_config, as we tend to call
them in i915 itself).
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to