diff options
author | Dave Airlie | 2019-03-29 02:01:04 +0100 |
---|---|---|
committer | Dave Airlie | 2019-03-29 02:01:05 +0100 |
commit | e0a3def2b15a4880ab84f8ad1cd7492fefb28ade (patch) | |
tree | 1ea00620d3460beb40fe8a9fbac3e173e0b65372 /drivers/gpu/drm/i915/intel_dp_mst.c | |
parent | Merge tag 'drm-intel-next-2019-03-20' of git://anongit.freedesktop.org/drm/dr... (diff) | |
parent | drm/i915: Update DRIVER_DATE to 20190328 (diff) | |
download | kernel-qcow2-linux-e0a3def2b15a4880ab84f8ad1cd7492fefb28ade.tar.gz kernel-qcow2-linux-e0a3def2b15a4880ab84f8ad1cd7492fefb28ade.tar.xz kernel-qcow2-linux-e0a3def2b15a4880ab84f8ad1cd7492fefb28ade.zip |
Merge tag 'drm-intel-next-2019-03-28' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
UAPI Changes:
- Make mmap code more asynchronous. Avoid full SET_DOMAIN on GTT mmap pagefault,
and flushes pages on acquisition instead. Moves some of the work from mmap fault
time to execbuf time to avoid lock contention during mmap access.
Has neutral to positive impact on perf as the flushing moves to execbuf time
in real world workloads on the current known userspaces due to recycling of BOs.
If there exist an unknown non-recycling userspace, they should explicitly do the
SET_DOMAIN and not rely on kernel doing implicit SET_DOMAIN because swapout/in
might have happenedt.
- Restore the accidentally removed behaviour of returning object size on GEM_CREATE
From 2011: ff72145badb8 ("drm: dumb scanout create/mmap for intel/radeon (v3)")
- Includes a some neutered patches to prepare to complete the earlier Mesa
recovery feature uAPI. Looking to enable this in the next PR.
Driver Changes:
- Add Elkhartlake (Gen11) support code and PCI IDs
- Add missing Amberlake PCI ID 0x87CA (Ville)
- Fix to Bugzilla #109780: Pick the first mode from EDID as the fixed mode when there is no preferred mode (Ville)
- Fix GCC 4.8 build by using __is_constexpr() (Chris, Randy, Uma)
- Add "Broadcast RGB", "force_audio" and "max_bpc" properties to DP MST (Ville)
- Remove 8bpc limitation from DP MST (Ville)
- Fix changing between limited and full range RGB output in DP fastsets (Ville)
- Reject unsupported HDR formats (Maarten)
- Handle YUV subpixel support better (Maarten)
- Various plane watermarks fixes and cleaning of the code (Ville)
- Icelake port sync master select fix (Manasi)
- Icelake VEBOX disable bitmask fix (Jose)
- Close a race where userspace could see incompletely initialized GEM context (Chris)
- Avoid C3 on i945gm to keep vblank interrupts steady (Ville)
- Avoid recalculating PLL HW readout each time (Lucas)
- A ton of patches to modularize uncore code (Daniel)
- Instead of storing media fuse value, immediately derive engine masks (Daniele)
- Reduce struct_mutex usage (Chris)
- Iterate over child devices to initialize ddi_port_info (Jani)
- Fixes to return correct error values when bailing out of functions (Dan)
- Use bitmap_zalloc() (Andy)
- Reorder and clarify Gen3/4 code (Ville)
- Refactor out common code in display mode handling (Ville)
- GuC code fixes (Sujaritha, Michal)
- Selftest improvements (Chris)
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190328151515.GA9606@jlahtine-desk.ger.corp.intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp_mst.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp_mst.c | 145 |
1 files changed, 95 insertions, 50 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index fb67cd931117..19d81cef2ab6 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -29,72 +29,108 @@ #include <drm/drm_edid.h> #include <drm/drm_probe_helper.h> +static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + struct link_config_limits *limits) +{ + struct drm_atomic_state *state = crtc_state->base.state; + struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); + struct intel_dp *intel_dp = &intel_mst->primary->dp; + struct intel_connector *connector = + to_intel_connector(conn_state->connector); + const struct drm_display_mode *adjusted_mode = + &crtc_state->base.adjusted_mode; + void *port = connector->port; + bool constant_n = drm_dp_has_quirk(&intel_dp->desc, + DP_DPCD_QUIRK_CONSTANT_N); + int bpp, slots = -EINVAL; + + crtc_state->lane_count = limits->max_lane_count; + crtc_state->port_clock = limits->max_clock; + + for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) { + crtc_state->pipe_bpp = bpp; + + crtc_state->pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, + crtc_state->pipe_bpp); + + slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr, + port, crtc_state->pbn); + if (slots == -EDEADLK) + return slots; + if (slots >= 0) + break; + } + + if (slots < 0) { + DRM_DEBUG_KMS("failed finding vcpi slots:%d\n", slots); + return slots; + } + + intel_link_compute_m_n(crtc_state->pipe_bpp, + crtc_state->lane_count, + adjusted_mode->crtc_clock, + crtc_state->port_clock, + &crtc_state->dp_m_n, + constant_n); + crtc_state->dp_m_n.tu = slots; + + return 0; +} + static int intel_dp_mst_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base); - struct intel_digital_port *intel_dig_port = intel_mst->primary; - struct intel_dp *intel_dp = &intel_dig_port->dp; - struct drm_connector *connector = conn_state->connector; - void *port = to_intel_connector(connector)->port; - struct drm_atomic_state *state = pipe_config->base.state; - struct drm_crtc *crtc = pipe_config->base.crtc; - struct drm_crtc_state *old_crtc_state = - drm_atomic_get_old_crtc_state(state, crtc); - int bpp; - int lane_count, slots = - to_intel_crtc_state(old_crtc_state)->dp_m_n.tu; - const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; - int mst_pbn; - bool constant_n = drm_dp_has_quirk(&intel_dp->desc, - DP_DPCD_QUIRK_CONSTANT_N); + struct intel_dp *intel_dp = &intel_mst->primary->dp; + struct intel_connector *connector = + to_intel_connector(conn_state->connector); + struct intel_digital_connector_state *intel_conn_state = + to_intel_digital_connector_state(conn_state); + const struct drm_display_mode *adjusted_mode = + &pipe_config->base.adjusted_mode; + void *port = connector->port; + struct link_config_limits limits; + int ret; if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) return -EINVAL; pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->has_pch_encoder = false; - bpp = 24; - if (intel_dp->compliance.test_data.bpc) { - bpp = intel_dp->compliance.test_data.bpc * 3; - DRM_DEBUG_KMS("Setting pipe bpp to %d\n", - bpp); - } + + if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) + pipe_config->has_audio = + drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, port); + else + pipe_config->has_audio = + intel_conn_state->force_audio == HDMI_AUDIO_ON; + /* * for MST we always configure max link bw - the spec doesn't * seem to suggest we should do otherwise. */ - lane_count = intel_dp_max_lane_count(intel_dp); - - pipe_config->lane_count = lane_count; + limits.min_clock = + limits.max_clock = intel_dp_max_link_rate(intel_dp); - pipe_config->pipe_bpp = bpp; + limits.min_lane_count = + limits.max_lane_count = intel_dp_max_lane_count(intel_dp); - pipe_config->port_clock = intel_dp_max_link_rate(intel_dp); + limits.min_bpp = 6 * 3; + limits.max_bpp = pipe_config->pipe_bpp; - if (drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, port)) - pipe_config->has_audio = true; + intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits); - mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp); - pipe_config->pbn = mst_pbn; - - slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr, port, - mst_pbn); - if (slots < 0) { - DRM_DEBUG_KMS("failed finding vcpi slots:%d\n", - slots); - return slots; - } - - intel_link_compute_m_n(bpp, lane_count, - adjusted_mode->crtc_clock, - pipe_config->port_clock, - &pipe_config->dp_m_n, - constant_n); + ret = intel_dp_mst_compute_link_config(encoder, pipe_config, + conn_state, &limits); + if (ret) + return ret; - pipe_config->dp_m_n.tu = slots; + pipe_config->limited_color_range = + intel_dp_limited_color_range(pipe_config, conn_state); if (IS_GEN9_LP(dev_priv)) pipe_config->lane_lat_optim_mask = @@ -117,7 +153,11 @@ intel_dp_mst_atomic_check(struct drm_connector *connector, struct drm_crtc *new_crtc = new_conn_state->crtc; struct drm_crtc_state *crtc_state; struct drm_dp_mst_topology_mgr *mgr; - int ret = 0; + int ret; + + ret = intel_digital_connector_atomic_check(connector, new_conn_state); + if (ret) + return ret; if (!old_conn_state->crtc) return 0; @@ -289,7 +329,7 @@ static void intel_mst_enable_dp(struct intel_encoder *encoder, DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); - if (intel_wait_for_register(dev_priv, + if (intel_wait_for_register(&dev_priv->uncore, DP_TP_STATUS(port), DP_TP_STATUS_ACT_SENT, DP_TP_STATUS_ACT_SENT, @@ -354,11 +394,13 @@ intel_dp_mst_detect(struct drm_connector *connector, bool force) static const struct drm_connector_funcs intel_dp_mst_connector_funcs = { .detect = intel_dp_mst_detect, .fill_modes = drm_helper_probe_single_connector_modes, + .atomic_get_property = intel_digital_connector_atomic_get_property, + .atomic_set_property = intel_digital_connector_atomic_set_property, .late_register = intel_connector_register, .early_unregister = intel_connector_unregister, .destroy = intel_connector_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_duplicate_state = intel_digital_connector_duplicate_state, }; static int intel_dp_mst_get_modes(struct drm_connector *connector) @@ -373,7 +415,6 @@ intel_dp_mst_mode_valid(struct drm_connector *connector, struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_dp *intel_dp = intel_connector->mst_port; int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; - int bpp = 24; /* MST uses fixed bpp */ int max_rate, mode_rate, max_lanes, max_link_clock; if (drm_connector_is_unregistered(connector)) @@ -386,7 +427,7 @@ intel_dp_mst_mode_valid(struct drm_connector *connector, max_lanes = intel_dp_max_lane_count(intel_dp); max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); - mode_rate = intel_dp_link_required(mode->clock, bpp); + mode_rate = intel_dp_link_required(mode->clock, 18); /* TODO - validate mode against available PBN for link */ if (mode->clock < 10000) @@ -487,6 +528,10 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo if (ret) goto err; + intel_attach_force_audio_property(connector); + intel_attach_broadcast_rgb_property(connector); + drm_connector_attach_max_bpc_property(connector, 6, 12); + return connector; err: |