All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
To: Matt Roper <matthew.d.roper@intel.com>,
	Uma Shankar <uma.shankar@intel.com>
Cc: intel-gfx@lists.freedesktop.org, ville.syrjala@intel.com,
	maarten.lankhorst@intel.com
Subject: Re: [v4 2/2] drm/i915/icl: Enable Plane Input CSC for YUV to RGB Conversion
Date: Fri, 26 Oct 2018 10:40:59 +0200	[thread overview]
Message-ID: <0ff02bbb-df70-34fc-ff2b-aa8a94b7f6d7@linux.intel.com> (raw)
In-Reply-To: <20181025221146.GD5732@mdroper-desk.amr.corp.intel.com>

Op 26-10-18 om 00:11 schreef Matt Roper:
> On Fri, Oct 26, 2018 at 03:33:38AM +0530, Uma Shankar wrote:
>> Plane input CSC needs to be enabled to convert frambuffers from
>> YUV to RGB. This is needed for bottom 3 planes on ICL, rest of
>> the planes have hardcoded conversion and taken care by the legacy
>> code.
>>
>> This patch defines the co-efficient values for YUV to RGB conversion
>> in BT709 and BT601 formats. It programs the coefficients and enables
>> the plane input csc unit in hardware.
>>
>> Note: This is currently untested and floated to get an early feedback
>> on the design and implementation for this feature. In parallel,
>> I will test this on actual ICL hardware and confirm with planar
>> formats.
>>
>> v2: Addressed Maarten's and Ville's review comments and added the
>> coefficients in a 2D array instead of independent Macros.
>>
>> v3: Added individual coefficient matrix (9 values) instead of 6
>> register values as per Maarten's comment. Also addresed a shift
>> issue with B channel coefficient.
>>
>> v4: Added support for Limited Range Color Handling
>>
>> Signed-off-by: Uma Shankar <uma.shankar@intel.com>
>> ---
>>  drivers/gpu/drm/i915/intel_color.c   | 79 ++++++++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/i915/intel_display.c | 23 ++++++++---
>>  drivers/gpu/drm/i915/intel_drv.h     |  2 +
>>  3 files changed, 98 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c
>> index 5127da2..3a52d92 100644
>> --- a/drivers/gpu/drm/i915/intel_color.c
>> +++ b/drivers/gpu/drm/i915/intel_color.c
>> @@ -57,6 +57,15 @@
>>  #define CSC_RGB_TO_YUV_RV_GV 0xbce89ad8
>>  #define CSC_RGB_TO_YUV_BV 0x1e080000
>>  
>> +#define  ROFF(x)          (((x) & 0xffff) << 16)
>> +#define  GOFF(x)          (((x) & 0xffff) << 0)
>> +#define  BOFF(x)          (((x) & 0xffff) << 16)
>> +
>> +/* Preoffset values for YUV to RGB Conversion */
>> +#define PREOFF_YUV_TO_RGB_HI		0x800
>> +#define PREOFF_YUV_TO_RGB_ME		0xF00
>> +#define PREOFF_YUV_TO_RGB_LO		0x800
> Doesn't bit #12 need to be set for each of these values (0x1800, 0x1F00,
> 0x1800)?  At least that's what I came up with based on the assumption
> that input CSC is programmed the same way as pipe CSC, but I might be
> overlooking or miscalculating something.
>
> The pipe CSC page gives an example of converting YUV to RGB with a table
> that matches your csc matrix below, and a note "Program the CSC
> Pre-Offsets to -1/2, -1/16, and -1/2."
>
> The bspec indicates the register values here are 13-bits (12:0 in the
> register dword) and are 2's complement fractions allowing values between
> -1 and 1 (exclusive).  So I take that to mean:
>
>     1/2                     = 0 1000 0000 0000
>     -1/2 (one's complement) = 1 0111 1111 1111
>     -1/2 (two's complement) = 1 1000 0000 0000 = 0x1800
>
> and
>
>     1/16                     = 0 0001 0000 0000
>     -1/16 (one's complement) = 1 1110 1111 1111
>     -1/16 (two's complement) = 1 1111 0000 0000 = 0x1F00
>
> Anyway, it would probably be good to give a comment indicating what the
> human-readable values you're using are supposed to be and an indication
> of how the register is programmed to represent those values.
>
>
> Matt
>
>> +
>>  /*
>>   * Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
>>   * format). This macro takes the coefficient we want transformed and the
>> @@ -643,6 +652,76 @@ int intel_color_check(struct drm_crtc *crtc,
>>  	return -EINVAL;
>>  }
>>  
>> +void icl_program_input_csc_coeff(const struct intel_crtc_state *crtc_state,
>> +				 const struct intel_plane_state *plane_state)
>> +{
>> +	struct drm_i915_private *dev_priv =
>> +		to_i915(plane_state->base.plane->dev);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	enum pipe pipe = crtc->pipe;
>> +	struct intel_plane *intel_plane =
>> +		to_intel_plane(plane_state->base.plane);
>> +	enum plane_id plane = intel_plane->id;
>> +
>> +	static const u16 input_csc_matrix[][9] = {
>> +		/* BT.601 full range YCbCr -> full range RGB */
>> +		[DRM_COLOR_YCBCR_BT601] = {
>> +			0x7AF8, 7800, 0x0,
>> +			0x8B28, 7800, 0x9AC0,
>> +			0x0, 7800, 0x7DD8,
>> +		},
>> +		/* BT.709 full range YCbCr -> full range RGB */
>> +		[DRM_COLOR_YCBCR_BT709] = {
>> +			0x7C98, 7800, 0x0,
>> +			0x9EF8, 7800, 0xABF8,
>> +			0x0, 0x7800,  0x7ED8,
>> +		},
>> +	};
>> +
>> +	/* Matrix for Limited Range to Full Range Conversion */
>> +	static const u16 input_csc_matrix_lr[][9] = {
>> +		/* BT.601 Limted range YCbCr -> full range RGB */
>> +		[DRM_COLOR_YCBCR_BT601] = {
>> +			0x7CC8, 7950, 0x0,
>> +			0x8CB8, 7918, 0x9C40,
>> +			0x0, 7918, 0x7FC8,
I think you forgot to add 0x to the second value, resulting in part hex, part numeric.

~Maarten
>> +		},
>> +		/* BT.709 Limited range YCbCr -> full range RGB */
>> +		[DRM_COLOR_YCBCR_BT709] = {
>> +			0x7EA8, 7950, 0x0,
>> +			0x8888, 7918, 0xADA8,
>> +			0x0, 0x7918,  0x6870,
>> +		},
>> +	};
>> +	const u16 *csc;
>> +
>> +	if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
>> +		csc = input_csc_matrix[plane_state->base.color_encoding];
>> +	else
>> +		csc = input_csc_matrix_lr[plane_state->base.color_encoding];
>> +
>> +	I915_WRITE(PLANE_INPUT_CSC_COEFF_REG(pipe, plane, 0), ROFF(csc[0]) |
>> +		   GOFF(csc[1]));
>> +	I915_WRITE(PLANE_INPUT_CSC_COEFF_REG(pipe, plane, 1), BOFF(csc[2]));
>> +	I915_WRITE(PLANE_INPUT_CSC_COEFF_REG(pipe, plane, 2), ROFF(csc[3]) |
>> +		   GOFF(csc[4]));
>> +	I915_WRITE(PLANE_INPUT_CSC_COEFF_REG(pipe, plane, 3), BOFF(csc[5]));
>> +	I915_WRITE(PLANE_INPUT_CSC_COEFF_REG(pipe, plane, 4), ROFF(csc[6]) |
>> +		   GOFF(csc[7]));
>> +	I915_WRITE(PLANE_INPUT_CSC_COEFF_REG(pipe, plane, 5), BOFF(csc[8]));
>> +
>> +	I915_WRITE(PLANE_INPUT_CSC_PREOFF_REG(pipe, plane, 0),
>> +		   PREOFF_YUV_TO_RGB_HI);
>> +	I915_WRITE(PLANE_INPUT_CSC_PREOFF_REG(pipe, plane, 1),
>> +		   PREOFF_YUV_TO_RGB_ME);
>> +	I915_WRITE(PLANE_INPUT_CSC_PREOFF_REG(pipe, plane, 2),
>> +		   PREOFF_YUV_TO_RGB_LO);
>> +
>> +	I915_WRITE(PLANE_INPUT_CSC_POSTOFF_REG(pipe, plane, 0), 0x0);
>> +	I915_WRITE(PLANE_INPUT_CSC_POSTOFF_REG(pipe, plane, 1), 0x0);
>> +	I915_WRITE(PLANE_INPUT_CSC_POSTOFF_REG(pipe, plane, 2), 0x0);
>> +}
>> +
>>  void intel_color_init(struct drm_crtc *crtc)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index fe045ab..d16a064 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -3666,6 +3666,7 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
>>  	struct drm_i915_private *dev_priv =
>>  		to_i915(plane_state->base.plane->dev);
>>  	const struct drm_framebuffer *fb = plane_state->base.fb;
>> +	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
>>  	u32 plane_color_ctl = 0;
>>  
>>  	if (INTEL_GEN(dev_priv) < 11) {
>> @@ -3676,13 +3677,23 @@ u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
>>  	plane_color_ctl |= glk_plane_color_ctl_alpha(plane_state);
>>  
>>  	if (fb->format->is_yuv) {
>> -		if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
>> -			plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
>> -		else
>> -			plane_color_ctl |= PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709;
>> +		if (!icl_is_hdr_plane(plane)) {
>> +			if (plane_state->base.color_encoding ==
>> +					DRM_COLOR_YCBCR_BT709)
>> +				plane_color_ctl |=
>> +					PLANE_COLOR_CSC_MODE_YUV709_TO_RGB709;
>> +			else
>> +				plane_color_ctl |=
>> +					PLANE_COLOR_CSC_MODE_YUV601_TO_RGB709;
>>  
>> -		if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
>> -			plane_color_ctl |= PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
>> +			if (plane_state->base.color_range ==
>> +					DRM_COLOR_YCBCR_FULL_RANGE)
>> +				plane_color_ctl |=
>> +				PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE;
>> +		} else {
>> +			icl_program_input_csc_coeff(crtc_state, plane_state);
>> +			plane_color_ctl |= PLANE_COLOR_INPUT_CSC_ENABLE;
>> +		}
>>  	}
>>  
>>  	return plane_color_ctl;
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>> index db24308..bd9e946 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -2285,6 +2285,8 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
>>  int intel_color_check(struct drm_crtc *crtc, struct drm_crtc_state *state);
>>  void intel_color_set_csc(struct drm_crtc_state *crtc_state);
>>  void intel_color_load_luts(struct drm_crtc_state *crtc_state);
>> +void icl_program_input_csc_coeff(const struct intel_crtc_state *crtc_state,
>> +				 const struct intel_plane_state *plane_state);
>>  
>>  /* intel_lspcon.c */
>>  bool lspcon_init(struct intel_digital_port *intel_dig_port);
>> -- 
>> 1.9.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2018-10-26  8:41 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-25 22:03 [v4 0/2] Enable Plane Input CSC for ICL Uma Shankar
2018-10-25 22:03 ` [v4 1/2] drm/i915/icl: Define Plane Input CSC Coefficient Registers Uma Shankar
2018-10-25 22:16   ` Matt Roper
2018-10-25 22:03 ` [v4 2/2] drm/i915/icl: Enable Plane Input CSC for YUV to RGB Conversion Uma Shankar
2018-10-25 22:11   ` Matt Roper
2018-10-26  8:40     ` Maarten Lankhorst [this message]
2018-10-26  9:24       ` Shankar, Uma
2018-10-25 22:48 ` ✗ Fi.CI.CHECKPATCH: warning for Enable Plane Input CSC for ICL (rev3) Patchwork
2018-10-25 22:49 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-10-25 23:09 ` ✓ Fi.CI.BAT: success " Patchwork
2018-10-26  6:03 ` ✗ Fi.CI.IGT: failure " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0ff02bbb-df70-34fc-ff2b-aa8a94b7f6d7@linux.intel.com \
    --to=maarten.lankhorst@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=maarten.lankhorst@intel.com \
    --cc=matthew.d.roper@intel.com \
    --cc=uma.shankar@intel.com \
    --cc=ville.syrjala@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.