All of lore.kernel.org
 help / color / mirror / Atom feed
From: Shashank Sharma <shashank.sharma@intel.com>
To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org
Cc: Ander Conselvan De Oliveira <ander.conselvan.de.oliveira@intel.com>
Subject: [PATCH v2 10/11] drm/i915: prepare ycbcr420 modeset
Date: Tue, 30 May 2017 17:43:49 +0530	[thread overview]
Message-ID: <1496146430-11430-11-git-send-email-shashank.sharma@intel.com> (raw)
In-Reply-To: <1496146430-11430-1-git-send-email-shashank.sharma@intel.com>

To get a ycbcr420 output from intel platforms, there are two
major steps:
- RGB->YCBCR conversion using a pipe CSC.
- Program PIPE_MISC register to generate a ycbcr420 output.
- Scaling down YCBCR444 samples to YCBCR420 samples using a pipe
  scaler.

This patch:
- Does scaler allocation for HDMI ycbcr420 outputs.
- Programs PIPE_MISC register for ycbcr420 output.
- Adds a new scaler user "HDMI output" to plug-into existing
  scaler framework. This output type is identified using bit
  30 of the scaler users bitmap.

Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Ander Conselvan De Oliveira <ander.conselvan.de.oliveira@intel.com>
Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h      |  3 +++
 drivers/gpu/drm/i915/intel_atomic.c  |  6 ++++++
 drivers/gpu/drm/i915/intel_display.c | 34 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h     | 10 +++++++++-
 drivers/gpu/drm/i915/intel_hdmi.c    | 11 +++++++++++
 drivers/gpu/drm/i915/intel_panel.c   |  3 ++-
 6 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 89888ad..1cb3bb4 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5026,6 +5026,9 @@ enum {
 
 #define _PIPE_MISC_A			0x70030
 #define _PIPE_MISC_B			0x71030
+#define   PIPEMISC_YCBCR420_ENABLE	(1<<27)
+#define   PIPEMISC_YCBCR420_MODE_BLEND	(1<<26)
+#define   PIPEMISC_OUTPUT_YCBCR		(1<<11)
 #define   PIPEMISC_DITHER_BPC_MASK	(7<<5)
 #define   PIPEMISC_DITHER_8_BPC		(0<<5)
 #define   PIPEMISC_DITHER_10_BPC	(1<<5)
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 50fb1f7..592b0d2 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -187,6 +187,12 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
 
 			/* panel fitter case: assign as a crtc scaler */
 			scaler_id = &scaler_state->scaler_id;
+		} else if (i == SKL_HDMI_OUTPUT_INDEX) {
+			name = "HDMI-OUTPUT";
+			idx = intel_crtc->base.base.id;
+
+			/* hdmi output case: needs a pipe scaler */
+			scaler_id = &scaler_state->scaler_id;
 		} else {
 			name = "PLANE";
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 58e4617..e5e3bc1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4623,6 +4623,11 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 		(src_h != dst_w || src_w != dst_h):
 		(src_w != dst_w || src_h != dst_h);
 
+	if (crtc_state->hdmi_output == DRM_HDMI_OUTPUT_YCBCR420
+		&& scaler_user == SKL_HDMI_OUTPUT_INDEX)
+		/* YCBCR 444 -> 420 conversion needs a scaler */
+		need_scaling = true;
+
 	/*
 	 * if plane is being disabled or scaler is no more required or force detach
 	 *  - free scaler binded to this plane/crtc
@@ -4670,6 +4675,26 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 }
 
 /**
+ * skl_update_scaler_hdmi_output - Stages update to scaler state for HDMI.
+ * HDMI YCBCR 420 output needs a scaler, for downsampling.
+ *
+ * @state: crtc's scaler state
+ *
+ * Return
+ *     0 - scaler_usage updated successfully
+ *    error - requested scaling cannot be supported or other error condition
+ */
+int skl_update_scaler_crtc_hdmi_output(struct intel_crtc_state *state)
+{
+	const struct drm_display_mode *mode = &state->base.adjusted_mode;
+
+	return skl_update_scaler(state, !state->base.active,
+		SKL_HDMI_OUTPUT_INDEX, &state->scaler_state.scaler_id,
+		DRM_MODE_ROTATE_0, state->pipe_src_w, state->pipe_src_h,
+		mode->crtc_hdisplay, mode->crtc_vdisplay);
+}
+
+/**
  * skl_update_scaler_crtc - Stages update to scaler state for a given crtc.
  *
  * @state: crtc's scaler state
@@ -8071,6 +8096,7 @@ static void haswell_set_pipemisc(struct drm_crtc *crtc)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	enum drm_hdmi_output_type hdmi_out = intel_crtc->config->hdmi_output;
 
 	if (IS_BROADWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 9) {
 		u32 val = 0;
@@ -8096,6 +8122,14 @@ static void haswell_set_pipemisc(struct drm_crtc *crtc)
 		if (intel_crtc->config->dither)
 			val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
 
+		if (hdmi_out) {
+			val |= PIPEMISC_OUTPUT_YCBCR;
+			if (hdmi_out == DRM_HDMI_OUTPUT_YCBCR420) {
+				val |= PIPEMISC_YCBCR420_ENABLE |
+				       PIPEMISC_YCBCR420_MODE_BLEND;
+			}
+		}
+
 		I915_WRITE(PIPEMISC(intel_crtc->pipe), val);
 	}
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a56e260..102570d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -462,7 +462,8 @@ struct intel_crtc_scaler_state {
 	 *
 	 *     If a bit is set, a user is using a scaler.
 	 *     Here user can be a plane or crtc as defined below:
-	 *       bits 0-30 - plane (bit position is index from drm_plane_index)
+	 *       bits 0-29 - plane (bit position is index from drm_plane_index)
+	 *       bit 30    - hdmi output
 	 *       bit 31    - crtc
 	 *
 	 * Instead of creating a new index to cover planes and crtc, using
@@ -475,6 +476,12 @@ struct intel_crtc_scaler_state {
 	 * avilability.
 	 */
 #define SKL_CRTC_INDEX 31
+
+	/*
+	 * HDMI YCBCR 420 output consume a scaler. So adding a user
+	 * for HDMI output 420 requirement.
+	 */
+#define SKL_HDMI_OUTPUT_INDEX 30
 	unsigned scaler_users;
 
 	/* scaler used by crtc for panel fitting purpose */
@@ -1485,6 +1492,7 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
 				 struct intel_crtc_state *pipe_config);
 
 int skl_update_scaler_crtc(struct intel_crtc_state *crtc_state);
+int skl_update_scaler_crtc_hdmi_output(struct intel_crtc_state *state);
 int skl_max_scale(struct intel_crtc *crtc, struct intel_crtc_state *crtc_state);
 
 static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 4b27b5d..5051347 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -1381,6 +1381,7 @@ intel_hdmi_compute_ycbcr_config(struct drm_connector_state *conn_state,
 {
 	struct drm_connector *connector = conn_state->connector;
 	struct drm_display_info *info = &connector->display_info;
+	struct intel_crtc *intel_crtc = to_intel_crtc(conn_state->crtc);
 	struct drm_display_mode *mode = &config->base.adjusted_mode;
 	enum drm_hdmi_output_type type = conn_state->hdmi_output;
 	u8 src_output_cap = intel_hdmi_get_src_output_support(connector);
@@ -1425,6 +1426,16 @@ intel_hdmi_compute_ycbcr_config(struct drm_connector_state *conn_state,
 		config->port_clock /= 2;
 		*clock_12bpc /= 2;
 		*clock_8bpc /= 2;
+
+		/* ycbcr 420 output conversion needs a scaler */
+		if (skl_update_scaler_crtc_hdmi_output(config)) {
+			DRM_ERROR("Scaler allocation for output failed\n");
+			return DRM_HDMI_OUTPUT_INVALID;
+		}
+
+		/* Bind this scaler to pipe */
+		intel_pch_panel_fitting(intel_crtc, config,
+					DRM_MODE_SCALE_FULLSCREEN);
 		break;
 
 	case DRM_HDMI_OUTPUT_YCBCR422:
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index c8103f8..4494190 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -110,7 +110,8 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
 
 	/* Native modes don't need fitting */
 	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
-	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h)
+	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h &&
+	    pipe_config->hdmi_output != DRM_HDMI_OUTPUT_YCBCR420)
 		goto done;
 
 	switch (fitting_mode) {
-- 
2.7.4

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

  parent reply	other threads:[~2017-05-30 12:13 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-30 12:13 [PATCH v2 00/11] HDMI YCBCR output handling in DRM layer Shashank Sharma
2017-05-30 12:13 ` [PATCH v2 01/11] drm: Add HDMI 2.0 VIC support for AVI info-frames Shashank Sharma
2017-05-30 16:13   ` Ville Syrjälä
2017-05-30 16:30     ` Sharma, Shashank
2017-05-31 12:41       ` Ville Syrjälä
2017-05-31 15:36         ` Sharma, Shashank
2017-06-01 19:29           ` Ville Syrjälä
2017-05-30 12:13 ` [PATCH v2 02/11] drm/edid: Complete CEA modedb(VIC 1-107) Shashank Sharma
2017-05-30 16:18   ` Ville Syrjälä
2017-05-30 16:26     ` Sharma, Shashank
2017-05-31 12:39       ` Ville Syrjälä
2017-05-31 15:31         ` Sharma, Shashank
2017-05-30 12:13 ` [PATCH v2 03/11] drm: parse ycbcr420 cmdb block Shashank Sharma
2017-05-30 16:27   ` Ville Syrjälä
2017-05-30 12:13 ` [PATCH v2 04/11] drm: parse ycbcr 420 deep color information Shashank Sharma
2017-05-30 16:32   ` Ville Syrjälä
2017-05-30 12:13 ` [PATCH v2 05/11] drm: create hdmi output property Shashank Sharma
2017-05-30 16:36   ` Ville Syrjälä
2017-05-30 16:48     ` Sharma, Shashank
2017-05-31 12:46       ` Ville Syrjälä
2017-05-31 13:04         ` Sharma, Shashank
2017-05-30 12:13 ` [PATCH v2 06/11] drm: set output colorspace in AVI infoframe Shashank Sharma
2017-05-30 12:13 ` [PATCH v2 07/11] drm: add ycbcr helper functions Shashank Sharma
2017-05-31  0:31   ` kbuild test robot
2017-05-30 12:13 ` [PATCH v2 08/11] drm/i915: handle ycbcr outputs Shashank Sharma
2017-05-30 22:36   ` kbuild test robot
2017-05-30 12:13 ` [PATCH v2 09/11] drm/i915: handle csc for ycbcr HDMI output Shashank Sharma
2017-05-30 12:13 ` Shashank Sharma [this message]
2017-05-30 12:13 ` [PATCH v2 11/11] drm/i915: set colorspace for ycbcr outputs Shashank Sharma
2017-05-30 13:53 ` ✗ Fi.CI.BAT: failure for HDMI YCBCR output handling in DRM layer (rev2) 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=1496146430-11430-11-git-send-email-shashank.sharma@intel.com \
    --to=shashank.sharma@intel.com \
    --cc=ander.conselvan.de.oliveira@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    /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.