diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_dp.c | 325 |
1 files changed, 233 insertions, 92 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 392c3653d0d7..7976fec88606 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -27,6 +27,8 @@ #include <linux/export.h> #include <linux/i2c.h> +#include <linux/log2.h> +#include <linux/math.h> #include <linux/notifier.h> #include <linux/seq_buf.h> #include <linux/slab.h> @@ -34,7 +36,6 @@ #include <linux/string_helpers.h> #include <linux/timekeeping.h> #include <linux/types.h> - #include <asm/byteorder.h> #include <drm/display/drm_dp_helper.h> @@ -45,12 +46,11 @@ #include <drm/drm_crtc.h> #include <drm/drm_edid.h> #include <drm/drm_fixed.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include "g4x_dp.h" -#include "i915_drv.h" -#include "i915_irq.h" -#include "i915_reg.h" +#include "i915_utils.h" #include "intel_alpm.h" #include "intel_atomic.h" #include "intel_audio.h" @@ -58,10 +58,13 @@ #include "intel_combo_phy_regs.h" #include "intel_connector.h" #include "intel_crtc.h" +#include "intel_crtc_state_dump.h" #include "intel_cx0_phy.h" #include "intel_ddi.h" #include "intel_de.h" #include "intel_display_driver.h" +#include "intel_display_regs.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dp.h" #include "intel_dp_aux.h" @@ -87,12 +90,10 @@ #include "intel_pfit.h" #include "intel_pps.h" #include "intel_psr.h" -#include "intel_runtime_pm.h" #include "intel_quirks.h" #include "intel_tc.h" #include "intel_vdsc.h" #include "intel_vrr.h" -#include "intel_crtc_state_dump.h" /* DP DSC throughput values used for slice count calculations KPixels/s */ #define DP_DSC_PEAK_PIXEL_RATE 2720000 @@ -846,7 +847,7 @@ small_joiner_ram_size_bits(struct intel_display *display) return 6144 * 8; } -u32 intel_dp_dsc_nearest_valid_bpp(struct intel_display *display, u32 bpp, u32 pipe_bpp) +static u32 intel_dp_dsc_nearest_valid_bpp(struct intel_display *display, u32 bpp, u32 pipe_bpp) { u32 bits_per_pixel = bpp; int i; @@ -938,6 +939,7 @@ static u32 ultrajoiner_ram_max_bpp(u32 mode_hdisplay) return ultrajoiner_ram_bits() / mode_hdisplay; } +/* TODO: return a bpp_x16 value */ static u32 get_max_compressed_bpp_with_joiner(struct intel_display *display, u32 mode_clock, u32 mode_hdisplay, @@ -954,6 +956,7 @@ u32 get_max_compressed_bpp_with_joiner(struct intel_display *display, return max_bpp; } +/* TODO: return a bpp_x16 value */ u16 intel_dp_dsc_get_max_compressed_bpp(struct intel_display *display, u32 link_clock, u32 lane_count, u32 mode_clock, u32 mode_hdisplay, @@ -1194,7 +1197,7 @@ intel_dp_output_format(struct intel_connector *connector, int intel_dp_min_bpp(enum intel_output_format output_format) { if (output_format == INTEL_OUTPUT_FORMAT_RGB) - return 6 * 3; + return intel_display_min_pipe_bpp(); else return 8 * 3; } @@ -1603,6 +1606,12 @@ int intel_dp_rate_select(struct intel_dp *intel_dp, int rate) void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, u8 *link_bw, u8 *rate_select) { + struct intel_display *display = to_intel_display(intel_dp); + + /* FIXME g4x can't generate an exact 2.7GHz with the 96MHz non-SSC refclk */ + if (display->platform.g4x && port_clock == 268800) + port_clock = 270000; + /* eDP 1.4 rate select method. */ if (intel_dp->use_rate_select) { *link_bw = 0; @@ -2066,7 +2075,7 @@ int intel_dp_dsc_sink_max_compressed_bpp(const struct intel_connector *connector pipe_config, bpc) >> 4; } -static int dsc_src_min_compressed_bpp(void) +int intel_dp_dsc_min_src_compressed_bpp(void) { /* Min Compressed bpp supported by source is 8 */ return 8; @@ -2098,7 +2107,7 @@ static int dsc_src_max_compressed_bpp(struct intel_dp *intel_dp) /* * Note: for pre-13 display you still need to check the validity of each step. */ -static int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector) +int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector) { struct intel_display *display = to_intel_display(connector); u8 incr = drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd); @@ -2106,12 +2115,19 @@ static int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector) if (DISPLAY_VER(display) < 14 || !incr) return fxp_q4_from_int(1); + if (connector->mst.dp && + !connector->link.force_bpp_x16 && !connector->mst.dp->force_dsc_fractional_bpp_en) + return fxp_q4_from_int(1); + /* fxp q4 */ return fxp_q4_from_int(1) / incr; } -/* Note: This is not universally usable! */ -static bool intel_dp_dsc_valid_bpp(struct intel_dp *intel_dp, int bpp_x16) +/* + * Note: for bpp_x16 to be valid it must be also within the source/sink's + * min..max bpp capability range. + */ +bool intel_dp_dsc_valid_compressed_bpp(struct intel_dp *intel_dp, int bpp_x16) { struct intel_display *display = to_intel_display(intel_dp); int i; @@ -2149,24 +2165,16 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, const struct intel_connector *connector = to_intel_connector(conn_state->connector); const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; int output_bpp; - int dsc_min_bpp; - int dsc_max_bpp; int min_bpp_x16, max_bpp_x16, bpp_step_x16; int dsc_joiner_max_bpp; int num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config); int bpp_x16; int ret; - dsc_min_bpp = fxp_q4_to_int_roundup(limits->link.min_bpp_x16); - dsc_joiner_max_bpp = get_max_compressed_bpp_with_joiner(display, adjusted_mode->clock, adjusted_mode->hdisplay, num_joined_pipes); - dsc_max_bpp = min(dsc_joiner_max_bpp, fxp_q4_to_int(limits->link.max_bpp_x16)); - - /* FIXME: remove the round trip via integers */ - min_bpp_x16 = fxp_q4_from_int(dsc_min_bpp); - max_bpp_x16 = fxp_q4_from_int(dsc_max_bpp); + max_bpp_x16 = min(fxp_q4_from_int(dsc_joiner_max_bpp), limits->link.max_bpp_x16); bpp_step_x16 = intel_dp_dsc_bpp_step_x16(connector); @@ -2174,8 +2182,12 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp); max_bpp_x16 = min(max_bpp_x16, fxp_q4_from_int(output_bpp) - bpp_step_x16); + drm_WARN_ON(display->drm, !is_power_of_2(bpp_step_x16)); + min_bpp_x16 = round_up(limits->link.min_bpp_x16, bpp_step_x16); + max_bpp_x16 = round_down(max_bpp_x16, bpp_step_x16); + for (bpp_x16 = max_bpp_x16; bpp_x16 >= min_bpp_x16; bpp_x16 -= bpp_step_x16) { - if (!intel_dp_dsc_valid_bpp(intel_dp, bpp_x16)) + if (!intel_dp_dsc_valid_compressed_bpp(intel_dp, bpp_x16)) continue; ret = dsc_compute_link_config(intel_dp, @@ -2478,7 +2490,7 @@ intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp, int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp; int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp; - dsc_src_min_bpp = dsc_src_min_compressed_bpp(); + dsc_src_min_bpp = intel_dp_dsc_min_src_compressed_bpp(); dsc_sink_min_bpp = intel_dp_dsc_sink_min_compressed_bpp(crtc_state); dsc_min_bpp = max(dsc_src_min_bpp, dsc_sink_min_bpp); limits->link.min_bpp_x16 = fxp_q4_from_int(dsc_min_bpp); @@ -2523,6 +2535,7 @@ intel_dp_dsc_compute_pipe_bpp_limits(struct intel_dp *intel_dp, bool intel_dp_compute_config_limits(struct intel_dp *intel_dp, + struct intel_connector *connector, struct intel_crtc_state *crtc_state, bool respect_downstream_limits, bool dsc, @@ -2576,7 +2589,7 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp, intel_dp_test_compute_config(intel_dp, crtc_state, limits); return intel_dp_compute_config_link_bpp_limits(intel_dp, - intel_dp->attached_connector, + connector, crtc_state, dsc, limits); @@ -2637,7 +2650,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes); dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en || - !intel_dp_compute_config_limits(intel_dp, pipe_config, + !intel_dp_compute_config_limits(intel_dp, connector, pipe_config, respect_downstream_limits, false, &limits); @@ -2671,7 +2684,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, str_yes_no(ret), str_yes_no(joiner_needs_dsc), str_yes_no(intel_dp->force_dsc_en)); - if (!intel_dp_compute_config_limits(intel_dp, pipe_config, + if (!intel_dp_compute_config_limits(intel_dp, connector, pipe_config, respect_downstream_limits, true, &limits)) @@ -3104,6 +3117,76 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state, } } +int intel_dp_compute_min_hblank(struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + const struct drm_display_mode *adjusted_mode = + &crtc_state->hw.adjusted_mode; + struct intel_connector *connector = to_intel_connector(conn_state->connector); + int symbol_size = intel_dp_is_uhbr(crtc_state) ? 32 : 8; + /* + * min symbol cycles is 3(BS,VBID, BE) for 128b/132b and + * 5(BS, VBID, MVID, MAUD, BE) for 8b/10b + */ + int min_sym_cycles = intel_dp_is_uhbr(crtc_state) ? 3 : 5; + bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); + int num_joined_pipes = intel_crtc_num_joined_pipes(crtc_state); + int min_hblank; + int max_lane_count = 4; + int hactive_sym_cycles, htotal_sym_cycles; + int dsc_slices = 0; + int link_bpp_x16; + + if (DISPLAY_VER(display) < 30) + return 0; + + /* MIN_HBLANK should be set only for 8b/10b MST or for 128b/132b SST/MST */ + if (!is_mst && !intel_dp_is_uhbr(crtc_state)) + return 0; + + if (crtc_state->dsc.compression_enable) { + dsc_slices = intel_dp_dsc_get_slice_count(connector, + adjusted_mode->crtc_clock, + adjusted_mode->crtc_hdisplay, + num_joined_pipes); + if (!dsc_slices) { + drm_dbg(display->drm, "failed to calculate dsc slice count\n"); + return -EINVAL; + } + } + + if (crtc_state->dsc.compression_enable) + link_bpp_x16 = crtc_state->dsc.compressed_bpp_x16; + else + link_bpp_x16 = fxp_q4_from_int(intel_dp_output_bpp(crtc_state->output_format, + crtc_state->pipe_bpp)); + + /* Calculate min Hblank Link Layer Symbol Cycle Count for 8b/10b MST & 128b/132b */ + hactive_sym_cycles = drm_dp_link_symbol_cycles(max_lane_count, + adjusted_mode->hdisplay, + dsc_slices, + link_bpp_x16, + symbol_size, is_mst); + htotal_sym_cycles = adjusted_mode->htotal * hactive_sym_cycles / + adjusted_mode->hdisplay; + + min_hblank = htotal_sym_cycles - hactive_sym_cycles; + /* minimum Hblank calculation: https://groups.vesa.org/wg/DP/document/20494 */ + min_hblank = max(min_hblank, min_sym_cycles); + + /* + * adjust the BlankingStart/BlankingEnd framing control from + * the calculated value + */ + min_hblank = min_hblank - 2; + + min_hblank = min(10, min_hblank); + crtc_state->min_hblank = min_hblank; + + return 0; +} + int intel_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, @@ -3203,6 +3286,10 @@ intel_dp_compute_config(struct intel_encoder *encoder, &pipe_config->dp_m_n); } + ret = intel_dp_compute_min_hblank(pipe_config, conn_state); + if (ret) + return ret; + /* FIXME: abstract this better */ if (pipe_config->splitter.enable) pipe_config->dp_m_n.data_m *= pipe_config->splitter.link_count; @@ -3223,7 +3310,7 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp, int link_rate, int lane_count) { memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set)); - intel_dp->link_trained = false; + intel_dp->link.active = false; intel_dp->needs_modeset_retry = false; intel_dp->link_rate = link_rate; intel_dp->lane_count = lane_count; @@ -3587,7 +3674,7 @@ void intel_dp_sync_state(struct intel_encoder *encoder, if (crtc_state) { intel_dp_reset_link_params(intel_dp); intel_dp_set_link_params(intel_dp, crtc_state->port_clock, crtc_state->lane_count); - intel_dp->link_trained = true; + intel_dp->link.active = true; } } @@ -3645,6 +3732,9 @@ static void intel_dp_get_pcon_dsc_cap(struct intel_dp *intel_dp) memset(intel_dp->pcon_dsc_dpcd, 0, sizeof(intel_dp->pcon_dsc_dpcd)); + if (!drm_dp_is_branch(intel_dp->dpcd)) + return; + if (drm_dp_dpcd_read(&intel_dp->aux, DP_PCON_DSC_ENCODER, intel_dp->pcon_dsc_dpcd, sizeof(intel_dp->pcon_dsc_dpcd)) < 0) @@ -4456,6 +4546,23 @@ intel_dp_mst_disconnect(struct intel_dp *intel_dp) static bool intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *esi) { + struct intel_display *display = to_intel_display(intel_dp); + + /* + * Display WA for HSD #13013007775: mtl/arl/lnl + * Read the sink count and link service IRQ registers in separate + * transactions to prevent disconnecting the sink on a TBT link + * inadvertently. + */ + if (IS_DISPLAY_VER(display, 14, 20) && !display->platform.battlemage) { + if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 3) != 3) + return false; + + /* DP_SINK_COUNT_ESI + 3 == DP_LINK_SERVICE_IRQ_VECTOR_ESI0 */ + return drm_dp_dpcd_readb(&intel_dp->aux, DP_LINK_SERVICE_IRQ_VECTOR_ESI0, + &esi[3]) == 1; + } + return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 4) == 4; } @@ -5005,8 +5112,6 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) bool link_ok = true; bool reprobe_needed = false; - drm_WARN_ON_ONCE(display->drm, intel_dp->mst.active_links < 0); - for (;;) { u8 esi[4] = {}; u8 ack[4] = {}; @@ -5021,7 +5126,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) drm_dbg_kms(display->drm, "DPRX ESI: %4ph\n", esi); - if (intel_dp->mst.active_links > 0 && link_ok && + if (intel_dp_mst_active_streams(intel_dp) > 0 && link_ok && esi[3] & LINK_STATUS_CHANGED) { if (!intel_dp_mst_link_status(intel_dp)) link_ok = false; @@ -5082,7 +5187,7 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp) { u8 link_status[DP_LINK_STATUS_SIZE]; - if (!intel_dp->link_trained) + if (!intel_dp->link.active) return false; /* @@ -5394,6 +5499,11 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) intel_psr_short_pulse(intel_dp); + if (intel_alpm_get_error(intel_dp)) { + intel_alpm_disable(intel_dp); + intel_dp->alpm_parameters.sink_alpm_error = true; + } + if (intel_dp_test_short_pulse(intel_dp)) reprobe_needed = true; @@ -5689,6 +5799,28 @@ intel_dp_detect_sdp_caps(struct intel_dp *intel_dp) drm_dp_as_sdp_supported(&intel_dp->aux, intel_dp->dpcd); } +static bool intel_dp_needs_dpcd_probe(struct intel_dp *intel_dp, bool force_on_external) +{ + struct intel_connector *connector = intel_dp->attached_connector; + + if (intel_dp_is_edp(intel_dp)) + return false; + + if (force_on_external) + return true; + + if (intel_dp->is_mst) + return false; + + return drm_edid_has_quirk(&connector->base, DRM_EDID_QUIRK_DP_DPCD_PROBE); +} + +void intel_dp_dpcd_set_probe(struct intel_dp *intel_dp, bool force_on_external) +{ + drm_dp_dpcd_set_probe(&intel_dp->aux, + intel_dp_needs_dpcd_probe(intel_dp, force_on_external)); +} + static int intel_dp_detect(struct drm_connector *_connector, struct drm_modeset_acquire_ctx *ctx, @@ -5817,6 +5949,8 @@ out_unset_edid: if (status != connector_status_connected && !intel_dp->is_mst) intel_dp_unset_edid(intel_dp); + intel_dp_dpcd_set_probe(intel_dp, false); + if (!intel_dp_is_edp(intel_dp)) drm_dp_set_subconnector_property(&connector->base, status, @@ -5829,23 +5963,26 @@ out_vdd_off: } static void -intel_dp_force(struct drm_connector *connector) +intel_dp_force(struct drm_connector *_connector) { - struct intel_display *display = to_intel_display(connector->dev); - struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); + connector->base.base.id, connector->base.name); if (!intel_display_driver_check_access(display)) return; intel_dp_unset_edid(intel_dp); - if (connector->status != connector_status_connected) + if (connector->base.status != connector_status_connected) return; intel_dp_set_edid(intel_dp); + + intel_dp_dpcd_set_probe(intel_dp, false); } static int intel_dp_get_modes(struct drm_connector *_connector) @@ -5881,24 +6018,25 @@ static int intel_dp_get_modes(struct drm_connector *_connector) } static int -intel_dp_connector_register(struct drm_connector *connector) +intel_dp_connector_register(struct drm_connector *_connector) { - struct intel_display *display = to_intel_display(connector->dev); - struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); int ret; - ret = intel_connector_register(connector); + ret = intel_connector_register(&connector->base); if (ret) return ret; drm_dbg_kms(display->drm, "registering %s bus for %s\n", - intel_dp->aux.name, connector->kdev->kobj.name); + intel_dp->aux.name, connector->base.kdev->kobj.name); - intel_dp->aux.dev = connector->kdev; + intel_dp->aux.dev = connector->base.kdev; ret = drm_dp_aux_register(&intel_dp->aux); if (!ret) - drm_dp_cec_register_connector(&intel_dp->aux, connector); + drm_dp_cec_register_connector(&intel_dp->aux, &connector->base); if (!intel_bios_encoder_is_lspcon(dig_port->base.devdata)) return ret; @@ -5909,20 +6047,21 @@ intel_dp_connector_register(struct drm_connector *connector) */ if (intel_lspcon_init(dig_port)) { if (intel_lspcon_detect_hdr_capability(dig_port)) - drm_connector_attach_hdr_output_metadata_property(connector); + drm_connector_attach_hdr_output_metadata_property(&connector->base); } return ret; } static void -intel_dp_connector_unregister(struct drm_connector *connector) +intel_dp_connector_unregister(struct drm_connector *_connector) { - struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); drm_dp_cec_unregister_connector(&intel_dp->aux); drm_dp_aux_unregister(&intel_dp->aux); - intel_connector_unregister(connector); + intel_connector_unregister(&connector->base); } void intel_dp_connector_sync_state(struct intel_connector *connector, @@ -5983,21 +6122,21 @@ static int intel_modeset_tile_group(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(state); struct drm_connector_list_iter conn_iter; - struct drm_connector *connector; + struct intel_connector *connector; int ret = 0; drm_connector_list_iter_begin(display->drm, &conn_iter); - drm_for_each_connector_iter(connector, &conn_iter) { + for_each_intel_connector_iter(connector, &conn_iter) { struct drm_connector_state *conn_state; struct intel_crtc_state *crtc_state; struct intel_crtc *crtc; - if (!connector->has_tile || - connector->tile_group->id != tile_group_id) + if (!connector->base.has_tile || + connector->base.tile_group->id != tile_group_id) continue; conn_state = drm_atomic_get_connector_state(&state->base, - connector); + &connector->base); if (IS_ERR(conn_state)) { ret = PTR_ERR(conn_state); break; @@ -6061,10 +6200,11 @@ static int intel_modeset_affected_transcoders(struct intel_atomic_state *state, } static int intel_modeset_synced_crtcs(struct intel_atomic_state *state, - struct drm_connector *connector) + struct drm_connector *_connector) { + struct intel_connector *connector = to_intel_connector(_connector); const struct drm_connector_state *old_conn_state = - drm_atomic_get_old_connector_state(&state->base, connector); + drm_atomic_get_old_connector_state(&state->base, &connector->base); const struct intel_crtc_state *old_crtc_state; struct intel_crtc *crtc; u8 transcoders; @@ -6086,17 +6226,18 @@ static int intel_modeset_synced_crtcs(struct intel_atomic_state *state, transcoders); } -static int intel_dp_connector_atomic_check(struct drm_connector *conn, +static int intel_dp_connector_atomic_check(struct drm_connector *_connector, struct drm_atomic_state *_state) { - struct intel_display *display = to_intel_display(conn->dev); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); struct intel_atomic_state *state = to_intel_atomic_state(_state); - struct drm_connector_state *conn_state = drm_atomic_get_new_connector_state(_state, conn); - struct intel_connector *intel_conn = to_intel_connector(conn); - struct intel_dp *intel_dp = enc_to_intel_dp(intel_conn->encoder); + struct drm_connector_state *conn_state = + drm_atomic_get_new_connector_state(_state, &connector->base); + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); int ret; - ret = intel_digital_connector_atomic_check(conn, &state->base); + ret = intel_digital_connector_atomic_check(&connector->base, &state->base); if (ret) return ret; @@ -6106,12 +6247,12 @@ static int intel_dp_connector_atomic_check(struct drm_connector *conn, return ret; } - if (!intel_connector_needs_modeset(state, conn)) + if (!intel_connector_needs_modeset(state, &connector->base)) return 0; ret = intel_dp_tunnel_atomic_check_state(state, intel_dp, - intel_conn); + connector); if (ret) return ret; @@ -6122,26 +6263,26 @@ static int intel_dp_connector_atomic_check(struct drm_connector *conn, if (DISPLAY_VER(display) < 9) return 0; - if (conn->has_tile) { - ret = intel_modeset_tile_group(state, conn->tile_group->id); + if (connector->base.has_tile) { + ret = intel_modeset_tile_group(state, connector->base.tile_group->id); if (ret) return ret; } - return intel_modeset_synced_crtcs(state, conn); + return intel_modeset_synced_crtcs(state, &connector->base); } -static void intel_dp_oob_hotplug_event(struct drm_connector *connector, +static void intel_dp_oob_hotplug_event(struct drm_connector *_connector, enum drm_connector_status hpd_state) { - struct intel_display *display = to_intel_display(connector->dev); - struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector)); - struct drm_i915_private *i915 = to_i915(connector->dev); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); + struct intel_encoder *encoder = intel_attached_encoder(connector); bool hpd_high = hpd_state == connector_status_connected; unsigned int hpd_pin = encoder->hpd_pin; bool need_work = false; - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); if (hpd_high != test_bit(hpd_pin, &display->hotplug.oob_hotplug_last_state)) { display->hotplug.event_bits |= BIT(hpd_pin); @@ -6150,10 +6291,10 @@ static void intel_dp_oob_hotplug_event(struct drm_connector *connector, hpd_high); need_work = true; } - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); if (need_work) - intel_hpd_schedule_detection(i915); + intel_hpd_schedule_detection(display); } static const struct drm_connector_funcs intel_dp_connector_funcs = { @@ -6180,13 +6321,12 @@ enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd) { struct intel_display *display = to_intel_display(dig_port); - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_dp *intel_dp = &dig_port->dp; u8 dpcd[DP_RECEIVER_CAP_SIZE]; if (dig_port->base.type == INTEL_OUTPUT_EDP && (long_hpd || - intel_runtime_pm_suspended(&i915->runtime_pm) || + intel_display_rpm_suspended(display) || !intel_pps_have_panel_power_or_vdd(intel_dp))) { /* * vdd off can generate a long/short pulse on eDP which @@ -6215,10 +6355,11 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd) * complete the DP tunnel BW request for the latter connector/encoder * waiting for this encoder's DPRX read, perform a dummy read here. */ - if (long_hpd) + if (long_hpd) { + intel_dp_dpcd_set_probe(intel_dp, true); + intel_dp_read_dprx_caps(intel_dp, dpcd); - if (long_hpd) { intel_dp->reset_link_params = true; intel_dp_invalidate_source_oui(intel_dp); @@ -6283,36 +6424,37 @@ intel_dp_has_gamut_metadata_dip(struct intel_encoder *encoder) } static void -intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector) +intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *_connector) { + struct intel_connector *connector = to_intel_connector(_connector); struct intel_display *display = to_intel_display(intel_dp); enum port port = dp_to_dig_port(intel_dp)->base.port; if (!intel_dp_is_edp(intel_dp)) - drm_connector_attach_dp_subconnector_property(connector); + drm_connector_attach_dp_subconnector_property(&connector->base); if (!display->platform.g4x && port != PORT_A) - intel_attach_force_audio_property(connector); + intel_attach_force_audio_property(&connector->base); - intel_attach_broadcast_rgb_property(connector); + intel_attach_broadcast_rgb_property(&connector->base); if (HAS_GMCH(display)) - drm_connector_attach_max_bpc_property(connector, 6, 10); + drm_connector_attach_max_bpc_property(&connector->base, 6, 10); else if (DISPLAY_VER(display) >= 5) - drm_connector_attach_max_bpc_property(connector, 6, 12); + drm_connector_attach_max_bpc_property(&connector->base, 6, 12); /* Register HDMI colorspace for case of lspcon */ if (intel_bios_encoder_is_lspcon(dp_to_dig_port(intel_dp)->base.devdata)) { - drm_connector_attach_content_type_property(connector); - intel_attach_hdmi_colorspace_property(connector); + drm_connector_attach_content_type_property(&connector->base); + intel_attach_hdmi_colorspace_property(&connector->base); } else { - intel_attach_dp_colorspace_property(connector); + intel_attach_dp_colorspace_property(&connector->base); } if (intel_dp_has_gamut_metadata_dip(&dp_to_dig_port(intel_dp)->base)) - drm_connector_attach_hdr_output_metadata_property(connector); + drm_connector_attach_hdr_output_metadata_property(&connector->base); if (HAS_VRR(display)) - drm_connector_attach_vrr_capable_property(connector); + drm_connector_attach_vrr_capable_property(&connector->base); } static void @@ -6347,7 +6489,6 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, struct intel_connector *connector) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct drm_display_mode *fixed_mode; struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; bool has_dpcd; @@ -6362,9 +6503,9 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, * eDP and LVDS bail out early in this case to prevent interfering * with an already powered-on LVDS power sequencer. */ - if (intel_get_lvds_encoder(dev_priv)) { + if (intel_get_lvds_encoder(display)) { drm_WARN_ON(display->drm, - !(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv))); + !(HAS_PCH_IBX(display) || HAS_PCH_CPT(display))); drm_info(display->drm, "LVDS was detected, not registering eDP\n"); @@ -6395,7 +6536,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, */ intel_hpd_enable_detection(encoder); - intel_alpm_init_dpcd(intel_dp); + intel_alpm_init(intel_dp); /* Cache DPCD and EDID for edp. */ has_dpcd = intel_edp_init_dpcd(intel_dp, connector); |