Commit 1bf2f3bf authored by Jani Nikula's avatar Jani Nikula

drm/i915/bios: add support for querying DSC details for encoder

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.

v3:
- use crtc_state instead of pipe_config
- return true by default from intel_bios_get_dsc_params()
- expand the comment about rc_buffer_block_size and rc_buffer_size

v2:
- make more robust, debug log errors better

Bspec: 29885
Cc: Vandita Kulkarni <vandita.kulkarni@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarVandita Kulkarni <vandita.kulkarni@intel.com>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/b895c349d964d70e4cad26f12a629ea1898bfcc2.1575974743.git.jani.nikula@intel.com
parent 6e0d46e9
......@@ -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"
......@@ -2394,6 +2395,104 @@ bool intel_bios_is_dsi_present(struct drm_i915_private *dev_priv,
return false;
}
static void fill_dsc(struct intel_crtc_state *crtc_state,
struct dsc_compression_parameters_entry *dsc,
int dsc_max_bpc)
{
struct drm_dsc_config *vdsc_cfg = &crtc_state->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("VBT: Unsupported BPC %d for DCS\n",
dsc_max_bpc);
crtc_state->pipe_bpp = bpc * 3;
crtc_state->dsc.compressed_bpp = min(crtc_state->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)) {
crtc_state->dsc.slice_count = 4;
} else if (dsc->slices_per_line & BIT(1)) {
crtc_state->dsc.slice_count = 2;
} else {
/* FIXME */
if (!(dsc->slices_per_line & BIT(0)))
DRM_DEBUG_KMS("VBT: Unsupported DSC slice count for DSI\n");
crtc_state->dsc.slice_count = 1;
}
if (crtc_state->hw.adjusted_mode.crtc_hdisplay %
crtc_state->dsc.slice_count != 0)
DRM_DEBUG_KMS("VBT: DSC hdisplay %d not divisible by slice count %d\n",
crtc_state->hw.adjusted_mode.crtc_hdisplay,
crtc_state->dsc.slice_count);
/*
* FIXME: Use VBT rc_buffer_block_size and rc_buffer_size for the
* implementation specific physical rate buffer size. Currently we use
* the required rate buffer model size calculated in
* drm_dsc_compute_rc_parameters() according to VESA DSC Annex E.
*
* The VBT rc_buffer_block_size and rc_buffer_size definitions
* correspond to DP 1.4 DPCD offsets 0x62 and 0x63. The DP DSC
* implementation should also use the DPCD (or perhaps VBT for eDP)
* provided value for the buffer size.
*/
/* 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 *crtc_state,
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 (crtc_state)
fill_dsc(crtc_state, devdata->dsc, dsc_max_bpc);
return true;
}
}
return false;
}
/**
* intel_bios_is_port_hpd_inverted - is HPD inverted for %port
* @i915: i915 device instance
......
......@@ -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 *crtc_state,
int dsc_max_bpc);
#endif /* _INTEL_BIOS_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment