diff options
author | Dave Airlie <airlied@redhat.com> | 2023-10-04 13:55:19 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2023-10-04 13:55:19 +1000 |
commit | 389af786f92ecdff35883551d54bf4e507ffcccb (patch) | |
tree | 6c08f598e39f3ccff1680ec5491408554407a284 /drivers/gpu/drm/i915/display/intel_dp_mst.c | |
parent | caacbdc28f545744770fb2caf347b3c4be9a6299 (diff) | |
parent | 3570bd989acc66add5726785058cceffa06b1f54 (diff) |
Merge tag 'drm-intel-next-2023-09-29' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
drm/i915 feature pull for v6.7:
Features and functionality:
- Early Xe2 LPD / Lunarlake (LNL) display enabling (Lucas, Matt, Gustavo,
Stanislav, Luca, Clint, Juha-Pekka, Balasubramani, Ravi)
- Plenty of various DSC improvements and fixes (Ankit)
- Add DSC PPS state readout and verification (Suraj)
- Improve fastsets for VRR, LRR and M/N updates (Ville)
- Use connector->ddc to create (non-DP MST) connector sysfs ddc symlinks (Ville)
- Various DSB improvements, load LUTs using DSB (Ville)
- Improve shared link bandwidth management, starting with FDI (Imre)
- Optimize get param ioctl for PXP status (Alan)
- Remove DG2 pre-production hardware workarounds (Matt)
- Add more RPL P/U PCI IDs (Dnyaneshwar)
- Add new DG2-G12 stepping (Swati)
- Add PSR sink error status to debugfs (Jouni)
- Add DP enhanced framing to crtc state checker (Ville)
Refactoring and cleanups:
- Simplify TileY/Tile4 tiling selftest enumeration (Matt)
- Remove some unused power domain code (Gustavo)
- Check stepping of display IP version rather than MTL platform (Matt)
- DP audio compute config cleanups (Vinod)
- SDVO cleanups and refactoring, more robust failure handling (Ville)
- Color register definition and readout cleanups (Jani)
- Reduce header interdependencies for frontbuffer tracking (Jani)
- Continue replacing struct edid with struct drm_edid (Jani)
- Use source physical address instead of EDID for CEC (Jani)
- Clean up Type-C port lane count functions (Luca)
- Clean up DSC PPS register definitions and readout (Jani)
- Stop using GEM_BUG_ON()/GEM_WARN_ON() in display code (Jani)
- Move more of the display probe to display code (Jani)
- Remove redundant runtime suspended state flag (Jouni)
- Move display info printing to display code (Balasubramani)
- Frontbuffer tracking improvements (Jouni)
- Add trailing newlines to debug logging (Jim Cromie)
- Separate display workarounds from clock gating init (Matt)
- Reduce dmesg log spamming for combo PHY, PLL state, FEC, DP MST (Ville, Imre)
Fixes:
- Fix hotplug poll detect loops via suspend/resume (Imre)
- Fix hotplug detect for forced connectors (Imre)
- Fix DSC first_line_bpg_offset calculation (Suraj)
- Fix debug prints for SDP CRC16 (Arun)
- Fix PXP runtime resume (Alan)
- Fix cx0 PHY lane handling (Gustavo)
- Fix frontbuffer tracking locking in debugfs (Juha-Pekka)
- Fix SDVO detect on some models (Ville)
- Fix SDP split configuration for DP MST (Vinod)
- Fix AUX usage and reads for HDCP on DP MST (Suraj)
- Fix PSR workaround (Jouni)
- Fix redundant AUX power get/put in DP force (Imre)
- Fix ICL DSI TCLK POST by letting hardware handle it (William)
- Fix IRQ reset for XE LP+ (Gustavo)
- Fix h/vsync_end instead of h/vtotal in VBT (Ville)
- Fix C20 PHY msgbus timeout issues (Gustavo)
- Fix pre-TGL FEC pipe A vs. DDI A mixup (Ville)
- Fix FEC state readout for DP MST (Ville)
DRM subsystem core changes:
- Assume sink supports 8 bpc when DSC is supported (Ankit)
- Add drm_edid_is_digital() helper (Jani)
- Parse source physical address from EDID (Jani)
- Add function to attach CEC without EDID (Jani)
- Reorder connector sysfs/debugfs remove (Ville)
- Register connector sysfs ddc symlink later (Ville)
Media subsystem changes:
- Add comments about CEC source physical address usage (Jani)
Merges:
- Backmerge drm-next to get v6.6-rc1 (Jani)
Signed-off-by: Dave Airlie <airlied@redhat.com>
# Conflicts:
# drivers/gpu/drm/i915/i915_drv.h
From: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/87r0mhi7a6.fsf@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp_mst.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_dp_mst.c | 156 |
1 files changed, 97 insertions, 59 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 5f73cdabe7a1..648cf37e02a8 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -155,15 +155,24 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder, const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; int slots = -EINVAL; + int link_bpp; - slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, limits->max_bpp, - limits->min_bpp, limits, + /* + * FIXME: allocate the BW according to link_bpp, which in the case of + * YUV420 is only half of the pipe bpp value. + */ + slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, + to_bpp_int(limits->link.max_bpp_x16), + to_bpp_int(limits->link.min_bpp_x16), + limits, conn_state, 2 * 3, false); if (slots < 0) return slots; - intel_link_compute_m_n(crtc_state->pipe_bpp, + link_bpp = intel_dp_output_bpp(crtc_state->output_format, crtc_state->pipe_bpp); + + intel_link_compute_m_n(link_bpp, crtc_state->lane_count, adjusted_mode->crtc_clock, crtc_state->port_clock, @@ -200,8 +209,8 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder, else dsc_max_bpc = min_t(u8, 10, conn_state->max_requested_bpc); - max_bpp = min_t(u8, dsc_max_bpc * 3, limits->max_bpp); - min_bpp = limits->min_bpp; + max_bpp = min_t(u8, dsc_max_bpc * 3, limits->pipe.max_bpp); + min_bpp = limits->pipe.min_bpp; num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd, dsc_bpc); @@ -228,6 +237,9 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder, if (max_bpp > sink_max_bpp) max_bpp = sink_max_bpp; + min_bpp = max(min_bpp, to_bpp_int_roundup(limits->link.min_bpp_x16)); + max_bpp = min(max_bpp, to_bpp_int(limits->link.max_bpp_x16)); + slots = intel_dp_mst_find_vcpi_slots_for_bpp(encoder, crtc_state, max_bpp, min_bpp, limits, conn_state, 2 * 3, true); @@ -290,17 +302,39 @@ static int intel_dp_mst_update_slots(struct intel_encoder *encoder, return 0; } -static bool intel_dp_mst_has_audio(const struct drm_connector_state *conn_state) +static bool +intel_dp_mst_compute_config_limits(struct intel_dp *intel_dp, + struct intel_crtc_state *crtc_state, + bool dsc, + struct link_config_limits *limits) { - const struct intel_digital_connector_state *intel_conn_state = - to_intel_digital_connector_state(conn_state); - struct intel_connector *connector = - to_intel_connector(conn_state->connector); + /* + * for MST we always configure max link bw - the spec doesn't + * seem to suggest we should do otherwise. + */ + limits->min_rate = limits->max_rate = + intel_dp_max_link_rate(intel_dp); - if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) - return connector->base.display_info.has_audio; - else - return intel_conn_state->force_audio == HDMI_AUDIO_ON; + limits->min_lane_count = limits->max_lane_count = + intel_dp_max_lane_count(intel_dp); + + limits->pipe.min_bpp = intel_dp_min_bpp(crtc_state->output_format); + /* + * FIXME: If all the streams can't fit into the link with + * their current pipe_bpp we should reduce pipe_bpp across + * the board until things start to fit. Until then we + * limit to <= 8bpc since that's what was hardcoded for all + * MST streams previously. This hack should be removed once + * we have the proper retry logic in place. + */ + limits->pipe.max_bpp = min(crtc_state->pipe_bpp, 24); + + intel_dp_adjust_compliance_config(intel_dp, crtc_state, limits); + + return intel_dp_compute_config_link_bpp_limits(intel_dp, + crtc_state, + dsc, + limits); } static int intel_dp_mst_compute_config(struct intel_encoder *encoder, @@ -313,7 +347,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; struct link_config_limits limits; - int ret; + bool dsc_needed; + int ret = 0; if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) return -EINVAL; @@ -322,42 +357,40 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->has_pch_encoder = false; - pipe_config->has_audio = - intel_dp_mst_has_audio(conn_state) && - intel_audio_compute_config(encoder, pipe_config, conn_state); + dsc_needed = intel_dp->force_dsc_en || + !intel_dp_mst_compute_config_limits(intel_dp, + pipe_config, + false, + &limits); - /* - * for MST we always configure max link bw - the spec doesn't - * seem to suggest we should do otherwise. - */ - limits.min_rate = - limits.max_rate = intel_dp_max_link_rate(intel_dp); + if (!dsc_needed) { + ret = intel_dp_mst_compute_link_config(encoder, pipe_config, + conn_state, &limits); - limits.min_lane_count = - limits.max_lane_count = intel_dp_max_lane_count(intel_dp); - - limits.min_bpp = intel_dp_min_bpp(pipe_config->output_format); - /* - * FIXME: If all the streams can't fit into the link with - * their current pipe_bpp we should reduce pipe_bpp across - * the board until things start to fit. Until then we - * limit to <= 8bpc since that's what was hardcoded for all - * MST streams previously. This hack should be removed once - * we have the proper retry logic in place. - */ - limits.max_bpp = min(pipe_config->pipe_bpp, 24); - - intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits); - - ret = intel_dp_mst_compute_link_config(encoder, pipe_config, - conn_state, &limits); + if (ret == -EDEADLK) + return ret; - if (ret == -EDEADLK) - return ret; + if (ret) + dsc_needed = true; + } /* enable compression if the mode doesn't fit available BW */ - drm_dbg_kms(&dev_priv->drm, "Force DSC en = %d\n", intel_dp->force_dsc_en); - if (ret || intel_dp->force_dsc_en) { + if (dsc_needed) { + drm_dbg_kms(&dev_priv->drm, "Try DSC (fallback=%s, force=%s)\n", + str_yes_no(ret), + str_yes_no(intel_dp->force_dsc_en)); + + if (!intel_dp_mst_compute_config_limits(intel_dp, + pipe_config, + true, + &limits)) + return -EINVAL; + + /* + * FIXME: As bpc is hardcoded to 8, as mentioned above, + * WARN and ignore the debug flag force_dsc_bpc for now. + */ + drm_WARN(&dev_priv->drm, intel_dp->force_dsc_bpc, "Cannot Force BPC for MST\n"); /* * Try to get at least some timeslots and then see, if * we can fit there with DSC. @@ -388,6 +421,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, pipe_config->lane_lat_optim_mask = bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); + intel_dp_audio_compute_config(encoder, pipe_config, conn_state); + intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); return 0; @@ -733,8 +768,8 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, ret = drm_dp_add_payload_part1(&intel_dp->mst_mgr, mst_state, drm_atomic_get_mst_payload_state(mst_state, connector->port)); if (ret < 0) - drm_err(&dev_priv->drm, "Failed to create MST payload for %s: %d\n", - connector->base.name, ret); + drm_dbg_kms(&dev_priv->drm, "Failed to create MST payload for %s: %d\n", + connector->base.name, ret); /* * Before Gen 12 this is not done as part of @@ -798,6 +833,8 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, intel_de_rmw(dev_priv, CHICKEN_TRANS(trans), 0, FECSTALL_DIS_DPTSTREAM_DPTTG); + intel_audio_sdp_split_update(pipe_config); + intel_enable_transcoder(pipe_config); intel_crtc_vblank_on(pipe_config); @@ -918,7 +955,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, int max_rate, mode_rate, max_lanes, max_link_clock; int ret; bool dsc = false, bigjoiner = false; - u16 dsc_max_output_bpp = 0; + u16 dsc_max_compressed_bpp = 0; u8 dsc_slice_count = 0; int target_clock = mode->clock; @@ -969,17 +1006,18 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, * TBD pass the connector BPC, * for now U8_MAX so that max BPC on that platform would be picked */ - int pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, U8_MAX); + int pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX); if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) { - dsc_max_output_bpp = - intel_dp_dsc_get_output_bpp(dev_priv, - max_link_clock, - max_lanes, - target_clock, - mode->hdisplay, - bigjoiner, - pipe_bpp, 64) >> 4; + dsc_max_compressed_bpp = + intel_dp_dsc_get_max_compressed_bpp(dev_priv, + max_link_clock, + max_lanes, + target_clock, + mode->hdisplay, + bigjoiner, + INTEL_OUTPUT_FORMAT_RGB, + pipe_bpp, 64); dsc_slice_count = intel_dp_dsc_get_slice_count(intel_dp, target_clock, @@ -987,7 +1025,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, bigjoiner); } - dsc = dsc_max_output_bpp && dsc_slice_count; + dsc = dsc_max_compressed_bpp && dsc_slice_count; } /* |