[5/9] drm/i915/bios: add support for querying DSC details for encoder
diff mbox series

Message ID 3eb365597774f9ba87a7201b96923fbde02ca459.1573227240.git.jani.nikula@intel.com
State New
Headers show
Series
  • drm/i915/dsi: enable DSC
Related show

Commit Message

Jani Nikula Nov. 8, 2019, 3:39 p.m. UTC
Add function for retrieving the DSC data for an encoder.

Initially, this is DSI specific, as DP does not use VBT settings for DSC
at all. It's also not very pretty.

In the future we might have a pointer from encoder to the child device,
which would make the child device list query here so much more sensible.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bios.c | 86 +++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_bios.h |  5 ++
 2 files changed, 91 insertions(+)

Patch
diff mbox series

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index 51068a0a1c42..522c399753fe 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -29,6 +29,7 @@ 
 #include <drm/i915_drm.h>
 
 #include "display/intel_display.h"
+#include "display/intel_display_types.h"
 #include "display/intel_gmbus.h"
 
 #include "i915_drv.h"
@@ -2229,6 +2230,91 @@  bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv,
 	return false;
 }
 
+static void fill_dsc(struct intel_crtc_state *pipe_config,
+		     struct dsc_compression_parameters_entry *dsc,
+		     int dsc_max_bpc)
+{
+	struct drm_dsc_config *vdsc_cfg = &pipe_config->dsc.config;
+	int bpc = 8;
+
+	vdsc_cfg->dsc_version_major = dsc->version_major;
+	vdsc_cfg->dsc_version_minor = dsc->version_minor;
+
+	if (dsc->support_12bpc && dsc_max_bpc >= 12)
+		bpc = 12;
+	else if (dsc->support_10bpc && dsc_max_bpc >= 10)
+		bpc = 10;
+	else if (dsc->support_8bpc && dsc_max_bpc >= 8)
+		bpc = 8;
+	else
+		DRM_DEBUG_KMS("Unsupported BPC for DCS\n"); /* FIXME */
+
+	pipe_config->pipe_bpp = bpc * 3;
+
+	pipe_config->dsc.compressed_bpp = min(pipe_config->pipe_bpp,
+					      VBT_DSC_MAX_BPP(dsc->max_bpp));
+
+	/*
+	 * FIXME: This is ugly, and slice count should take DSC engine
+	 * throughput etc. into account.
+	 *
+	 * Also, per spec DSI supports 1, 2, 3 or 4 horizontal slices.
+	 */
+	if (dsc->slices_per_line & BIT(2) &&
+	    pipe_config->hw.adjusted_mode.crtc_hdisplay % 4 == 0) {
+		pipe_config->dsc.slice_count = 4;
+	} else if (dsc->slices_per_line & BIT(1) &&
+		   pipe_config->hw.adjusted_mode.crtc_hdisplay % 2 == 0) {
+		pipe_config->dsc.slice_count = 2;
+	} else {
+		/* FIXME */
+		if (!(dsc->slices_per_line & BIT(0)))
+			DRM_DEBUG_KMS("Unsupported slice count for DSI DCS\n");
+
+		pipe_config->dsc.slice_count = 1;
+	}
+
+	/* FIXME: rc_buffer_block_size, using defaults in intel_vdsc.c */
+
+	/* FIXME: rc_buffer_size, using defaults in intel_vdsc.c */
+
+	/* FIXME: DSI spec says bpc + 1 for this one */
+	vdsc_cfg->line_buf_depth = VBT_DSC_LINE_BUFFER_DEPTH(dsc->line_buffer_depth);
+
+	vdsc_cfg->block_pred_enable = dsc->block_prediction_enable;
+
+	vdsc_cfg->slice_height = dsc->slice_height;
+}
+
+/* FIXME: initially DSI specific */
+bool intel_bios_get_dsc_params(struct intel_encoder *encoder,
+			       struct intel_crtc_state *pipe_config,
+			       int dsc_max_bpc)
+{
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+	const struct display_device_data *devdata;
+	const struct child_device_config *child;
+
+	list_for_each_entry(devdata, &i915->vbt.display_devices, node) {
+		child = &devdata->child;
+
+		if (!(child->device_type & DEVICE_TYPE_MIPI_OUTPUT))
+			continue;
+
+		if (child->dvo_port - DVO_PORT_MIPIA == encoder->port) {
+			if (!devdata->dsc)
+				return false;
+
+			if (pipe_config)
+				fill_dsc(pipe_config, devdata->dsc, dsc_max_bpc);
+
+			return true;
+		}
+	}
+
+	return true;
+}
+
 /**
  * intel_bios_is_port_hpd_inverted - is HPD inverted for %port
  * @i915:	i915 device instance
diff --git a/drivers/gpu/drm/i915/display/intel_bios.h b/drivers/gpu/drm/i915/display/intel_bios.h
index 98f064828a57..fe1a11d3d6b6 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.h
+++ b/drivers/gpu/drm/i915/display/intel_bios.h
@@ -35,6 +35,8 @@ 
 #include <drm/i915_drm.h>
 
 struct drm_i915_private;
+struct intel_crtc_state;
+struct intel_encoder;
 enum port;
 
 enum intel_backlight_type {
@@ -242,5 +244,8 @@  bool intel_bios_is_port_hpd_inverted(const struct drm_i915_private *i915,
 bool intel_bios_is_lspcon_present(const struct drm_i915_private *i915,
 				  enum port port);
 enum aux_ch intel_bios_port_aux_ch(struct drm_i915_private *dev_priv, enum port port);
+bool intel_bios_get_dsc_params(struct intel_encoder *encoder,
+			       struct intel_crtc_state *pipe_config,
+			       int dsc_max_bpc);
 
 #endif /* _INTEL_BIOS_H_ */