Message ID | 20171019133721.11794-6-ville.syrjala@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Op 19-10-17 om 15:37 schreef Ville Syrjala: > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > Currently the DDI encoder->type will change at runtime depending on > what kind of hotplugs we've processed. That's quite bad since we can't > really trust that that current value of encoder->type actually matches > the type of signal we're trying to drive through it. > > Let's eliminate that problem by declaring that non-eDP DDI port will > always have the encoder type as INTEL_OUTPUT_DDI. This means the code > can no longer try to distinguish DP vs. HDMI based on encoder->type. > We'll leave eDP as INTEL_OUTPUT_EDP, since it'll never change and > there's a bunch of code that relies on that value to identify eDP > encoders. > > We'll introduce a new encoder .compute_output_type() hook. This allows > us to compute the full output_types before any encoder .compute_config() > hooks get called, thus those hooks can rely on output_types being > correct, which is useful for cloning on oldr platforms. For now we'll > just look at the connector type and pick the correct mode based on that. > In the future the new hook could be used to implement dynamic switching > between LS and PCON modes for LSPCON. > > TODO: maybe make .get_config() populate output_types rather than doing > the default encoder->type thing in caller and then undoing it for > DDI in .get_config(). > > v2: Fix BXT/GLK PPS explosion with DSI/MST encoders > v3: Avoid the PPS warn on pure HDMI/DVI DDI encoders by checking dp.output_reg > v4: Rebase > v5: Populate output_types in .get_config() rather than in the caller Could we get rid of compute_output_type in this patch? Perhaps do it as preliminary patch towards removing the use? Rest of the series except patch 8 looks good. For patch 1-4, 6, 7, 9 (if the delta between ddi_get_config and old mst get_config is harmless or beneficial) and 10: Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Thanks for the work towards cleaning this mess up. ~Maarten > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > --- > drivers/gpu/drm/i915/i915_debugfs.c | 2 +- > drivers/gpu/drm/i915/intel_crt.c | 2 ++ > drivers/gpu/drm/i915/intel_ddi.c | 43 ++++++++++++++++++++++++++++------- > drivers/gpu/drm/i915/intel_display.c | 16 +++++++------ > drivers/gpu/drm/i915/intel_dp.c | 24 +++++++++---------- > drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++ > drivers/gpu/drm/i915/intel_drv.h | 7 ++++-- > drivers/gpu/drm/i915/intel_dsi.c | 2 ++ > drivers/gpu/drm/i915/intel_dvo.c | 2 ++ > drivers/gpu/drm/i915/intel_hdmi.c | 12 ++++------ > drivers/gpu/drm/i915/intel_lvds.c | 2 ++ > drivers/gpu/drm/i915/intel_opregion.c | 2 +- > drivers/gpu/drm/i915/intel_sdvo.c | 2 ++ > drivers/gpu/drm/i915/intel_tv.c | 2 ++ > 14 files changed, 80 insertions(+), 40 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c > index c65e381b85f3..e5333bfdf32d 100644 > --- a/drivers/gpu/drm/i915/i915_debugfs.c > +++ b/drivers/gpu/drm/i915/i915_debugfs.c > @@ -3049,7 +3049,7 @@ static void intel_connector_info(struct seq_file *m, > break; > case DRM_MODE_CONNECTOR_HDMIA: > if (intel_encoder->type == INTEL_OUTPUT_HDMI || > - intel_encoder->type == INTEL_OUTPUT_UNKNOWN) > + intel_encoder->type == INTEL_OUTPUT_DDI) > intel_hdmi_info(m, intel_connector); > break; > default: > diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c > index 668e8c3e791d..a61e61efe9aa 100644 > --- a/drivers/gpu/drm/i915/intel_crt.c > +++ b/drivers/gpu/drm/i915/intel_crt.c > @@ -119,6 +119,8 @@ static unsigned int intel_crt_get_flags(struct intel_encoder *encoder) > static void intel_crt_get_config(struct intel_encoder *encoder, > struct intel_crtc_state *pipe_config) > { > + pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); > + > pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder); > > pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c > index c8790bb74839..630609575db4 100644 > --- a/drivers/gpu/drm/i915/intel_ddi.c > +++ b/drivers/gpu/drm/i915/intel_ddi.c > @@ -497,10 +497,8 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *encoder) > switch (encoder->type) { > case INTEL_OUTPUT_DP_MST: > return enc_to_mst(&encoder->base)->primary->port; > - case INTEL_OUTPUT_DP: > case INTEL_OUTPUT_EDP: > - case INTEL_OUTPUT_HDMI: > - case INTEL_OUTPUT_UNKNOWN: > + case INTEL_OUTPUT_DDI: > return enc_to_dig_port(&encoder->base)->port; > case INTEL_OUTPUT_ANALOG: > return PORT_E; > @@ -1532,6 +1530,7 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, > struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; > uint32_t temp; > + > temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); > if (state == true) > temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC; > @@ -2586,12 +2585,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder, > pipe_config->hdmi_high_tmds_clock_ratio = true; > /* fall through */ > case TRANS_DDI_MODE_SELECT_DVI: > + pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); > pipe_config->lane_count = 4; > break; > case TRANS_DDI_MODE_SELECT_FDI: > + pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); > break; > case TRANS_DDI_MODE_SELECT_DP_SST: > + if (encoder->type == INTEL_OUTPUT_EDP) > + pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); > + else > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); > + pipe_config->lane_count = > + ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; > + intel_dp_get_m_n(intel_crtc, pipe_config); > + break; > case TRANS_DDI_MODE_SELECT_DP_MST: > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); > pipe_config->lane_count = > ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; > intel_dp_get_m_n(intel_crtc, pipe_config); > @@ -2630,21 +2640,36 @@ void intel_ddi_get_config(struct intel_encoder *encoder, > bxt_ddi_phy_get_lane_lat_optim_mask(encoder); > } > > +static enum intel_output_type > +intel_ddi_compute_output_type(struct intel_encoder *encoder, > + struct intel_crtc_state *crtc_state, > + struct drm_connector_state *conn_state) > +{ > + switch (conn_state->connector->connector_type) { > + case DRM_MODE_CONNECTOR_HDMIA: > + return INTEL_OUTPUT_HDMI; > + case DRM_MODE_CONNECTOR_eDP: > + return INTEL_OUTPUT_EDP; > + case DRM_MODE_CONNECTOR_DisplayPort: > + return INTEL_OUTPUT_DP; > + default: > + MISSING_CASE(conn_state->connector->connector_type); > + return INTEL_OUTPUT_UNUSED; > + } > +} > + > static bool intel_ddi_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); > - int type = encoder->type; > int port = intel_ddi_get_encoder_port(encoder); > int ret; > > - WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); > - > if (port == PORT_A) > pipe_config->cpu_transcoder = TRANSCODER_EDP; > > - if (type == INTEL_OUTPUT_HDMI) > + if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) > ret = intel_hdmi_compute_config(encoder, pipe_config, conn_state); > else > ret = intel_dp_compute_config(encoder, pipe_config, conn_state); > @@ -2764,6 +2789,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) > drm_encoder_init(&dev_priv->drm, encoder, &intel_ddi_funcs, > DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port)); > > + intel_encoder->compute_output_type = intel_ddi_compute_output_type; > intel_encoder->compute_config = intel_ddi_compute_config; > intel_encoder->enable = intel_enable_ddi; > if (IS_GEN9_LP(dev_priv)) > @@ -2821,9 +2847,10 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) > } > } > > + intel_dig_port->dp.output_reg = INVALID_MMIO_REG; > intel_dig_port->max_lanes = max_lanes; > > - intel_encoder->type = INTEL_OUTPUT_UNKNOWN; > + intel_encoder->type = INTEL_OUTPUT_DDI; > intel_encoder->power_domain = intel_port_to_power_domain(port); > intel_encoder->port = port; > intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index bd62c0a65bcd..a7e02ae33583 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -10591,7 +10591,7 @@ static const char * const output_type_str[] = { > OUTPUT_TYPE(DP), > OUTPUT_TYPE(EDP), > OUTPUT_TYPE(DSI), > - OUTPUT_TYPE(UNKNOWN), > + OUTPUT_TYPE(DDI), > OUTPUT_TYPE(DP_MST), > }; > > @@ -10762,7 +10762,7 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state) > > switch (encoder->type) { > unsigned int port_mask; > - case INTEL_OUTPUT_UNKNOWN: > + case INTEL_OUTPUT_DDI: > if (WARN_ON(!HAS_DDI(to_i915(dev)))) > break; > case INTEL_OUTPUT_DP: > @@ -10895,7 +10895,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, > * Determine output_types before calling the .compute_config() > * hooks so that the hooks can use this information safely. > */ > - pipe_config->output_types |= 1 << encoder->type; > + if (encoder->compute_output_type) > + pipe_config->output_types |= > + BIT(encoder->compute_output_type(encoder, pipe_config, > + connector_state)); > + else > + pipe_config->output_types |= BIT(encoder->type); > } > > encoder_retry: > @@ -11572,10 +11577,8 @@ verify_crtc_state(struct drm_crtc *crtc, > "Encoder connected to wrong pipe %c\n", > pipe_name(pipe)); > > - if (active) { > - pipe_config->output_types |= 1 << encoder->type; > + if (active) > encoder->get_config(encoder, pipe_config); > - } > } > > intel_crtc_compute_pixel_rate(pipe_config); > @@ -14963,7 +14966,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) > crtc_state = to_intel_crtc_state(crtc->base.state); > > encoder->base.crtc = &crtc->base; > - crtc_state->output_types |= 1 << encoder->type; > encoder->get_config(encoder, crtc_state); > } else { > encoder->base.crtc = NULL; > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index aa75f55eeb61..2b482d12000e 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -758,11 +758,16 @@ void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) > struct intel_dp *intel_dp; > > if (encoder->type != INTEL_OUTPUT_DP && > - encoder->type != INTEL_OUTPUT_EDP) > + encoder->type != INTEL_OUTPUT_EDP && > + encoder->type != INTEL_OUTPUT_DDI) > continue; > > intel_dp = enc_to_intel_dp(&encoder->base); > > + /* Skip pure DVI/HDMI DDI encoders */ > + if (!i915_mmio_reg_valid(intel_dp->output_reg)) > + continue; > + > WARN_ON(intel_dp->active_pipe != INVALID_PIPE); > > if (encoder->type != INTEL_OUTPUT_EDP) > @@ -2603,6 +2608,11 @@ static void intel_dp_get_config(struct intel_encoder *encoder, > enum port port = dp_to_dig_port(intel_dp)->port; > struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); > > + if (encoder->type == INTEL_OUTPUT_EDP) > + pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); > + else > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); > + > tmp = I915_READ(intel_dp->output_reg); > > pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A; > @@ -4699,8 +4709,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) > { > struct drm_connector *connector = &intel_connector->base; > struct intel_dp *intel_dp = intel_attached_dp(connector); > - struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); > - struct intel_encoder *intel_encoder = &intel_dig_port->base; > struct drm_device *dev = connector->dev; > enum drm_connector_status status; > u8 sink_irq_vector = 0; > @@ -4733,9 +4741,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) > goto out; > } > > - if (intel_encoder->type != INTEL_OUTPUT_EDP) > - intel_encoder->type = INTEL_OUTPUT_DP; > - > if (intel_dp->reset_link_params) { > /* Initial max link lane count */ > intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); > @@ -4852,9 +4857,6 @@ intel_dp_force(struct drm_connector *connector) > intel_dp_set_edid(intel_dp); > > intel_display_power_put(dev_priv, intel_dp->aux_power_domain); > - > - if (intel_encoder->type != INTEL_OUTPUT_EDP) > - intel_encoder->type = INTEL_OUTPUT_DP; > } > > static int intel_dp_get_modes(struct drm_connector *connector) > @@ -5073,10 +5075,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) > struct drm_i915_private *dev_priv = to_i915(dev); > enum irqreturn ret = IRQ_NONE; > > - if (intel_dig_port->base.type != INTEL_OUTPUT_EDP && > - intel_dig_port->base.type != INTEL_OUTPUT_HDMI) > - intel_dig_port->base.type = INTEL_OUTPUT_DP; > - > if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { > /* > * vdd off can generate a long pulse on eDP which > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c > index 772521440a9f..9be6f32bb100 100644 > --- a/drivers/gpu/drm/i915/intel_dp_mst.c > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c > @@ -270,6 +270,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, > enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; > u32 temp, flags = 0; > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); > + > pipe_config->has_audio = > intel_ddi_is_audio_enabled(dev_priv, crtc); > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index a05ab3a1ab27..650129980ce2 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -173,7 +173,7 @@ enum intel_output_type { > INTEL_OUTPUT_DP = 7, > INTEL_OUTPUT_EDP = 8, > INTEL_OUTPUT_DSI = 9, > - INTEL_OUTPUT_UNKNOWN = 10, > + INTEL_OUTPUT_DDI = 10, > INTEL_OUTPUT_DP_MST = 11, > }; > > @@ -216,6 +216,9 @@ struct intel_encoder { > enum port port; > unsigned int cloneable; > void (*hot_plug)(struct intel_encoder *); > + enum intel_output_type (*compute_output_type)(struct intel_encoder *, > + struct intel_crtc_state *, > + struct drm_connector_state *); > bool (*compute_config)(struct intel_encoder *, > struct intel_crtc_state *, > struct drm_connector_state *); > @@ -1149,7 +1152,7 @@ enc_to_dig_port(struct drm_encoder *encoder) > struct intel_encoder *intel_encoder = to_intel_encoder(encoder); > > switch (intel_encoder->type) { > - case INTEL_OUTPUT_UNKNOWN: > + case INTEL_OUTPUT_DDI: > WARN_ON(!HAS_DDI(to_i915(encoder->dev))); > case INTEL_OUTPUT_DP: > case INTEL_OUTPUT_EDP: > diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c > index 66bbedc5fa01..2ae3eea19317 100644 > --- a/drivers/gpu/drm/i915/intel_dsi.c > +++ b/drivers/gpu/drm/i915/intel_dsi.c > @@ -1243,6 +1243,8 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, > u32 pclk; > DRM_DEBUG_KMS("\n"); > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI); > + > if (IS_GEN9_LP(dev_priv)) > bxt_dsi_get_pipe_config(encoder, pipe_config); > > diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c > index 53c9b763f4ce..754baa00bea9 100644 > --- a/drivers/gpu/drm/i915/intel_dvo.c > +++ b/drivers/gpu/drm/i915/intel_dvo.c > @@ -159,6 +159,8 @@ static void intel_dvo_get_config(struct intel_encoder *encoder, > struct intel_dvo *intel_dvo = enc_to_dvo(encoder); > u32 tmp, flags = 0; > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DVO); > + > tmp = I915_READ(intel_dvo->dev.dvo_reg); > if (tmp & DVO_HSYNC_ACTIVE_HIGH) > flags |= DRM_MODE_FLAG_PHSYNC; > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > index 5132dc814788..1ff448a67b99 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -957,6 +957,8 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, > u32 tmp, flags = 0; > int dotclock; > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); > + > tmp = I915_READ(intel_hdmi->hdmi_reg); > > if (tmp & SDVO_HSYNC_ACTIVE_HIGH) > @@ -1610,12 +1612,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) > > intel_hdmi_unset_edid(connector); > > - if (intel_hdmi_set_edid(connector)) { > - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > - > - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; > + if (intel_hdmi_set_edid(connector)) > status = connector_status_connected; > - } else > + else > status = connector_status_disconnected; > > intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); > @@ -1626,8 +1625,6 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) > static void > intel_hdmi_force(struct drm_connector *connector) > { > - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > - > DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", > connector->base.id, connector->name); > > @@ -1637,7 +1634,6 @@ intel_hdmi_force(struct drm_connector *connector) > return; > > intel_hdmi_set_edid(connector); > - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; > } > > static int intel_hdmi_get_modes(struct drm_connector *connector) > diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c > index 38572d65e46e..ef80499113ee 100644 > --- a/drivers/gpu/drm/i915/intel_lvds.c > +++ b/drivers/gpu/drm/i915/intel_lvds.c > @@ -125,6 +125,8 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, > struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); > u32 tmp, flags = 0; > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_LVDS); > + > tmp = I915_READ(lvds_encoder->reg); > if (tmp & LVDS_HSYNC_POLARITY) > flags |= DRM_MODE_FLAG_NHSYNC; > diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c > index 1d946240e55f..39714be3eb6b 100644 > --- a/drivers/gpu/drm/i915/intel_opregion.c > +++ b/drivers/gpu/drm/i915/intel_opregion.c > @@ -383,7 +383,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, > case INTEL_OUTPUT_ANALOG: > type = DISPLAY_TYPE_CRT; > break; > - case INTEL_OUTPUT_UNKNOWN: > + case INTEL_OUTPUT_DDI: > case INTEL_OUTPUT_DP: > case INTEL_OUTPUT_HDMI: > case INTEL_OUTPUT_DP_MST: > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c > index 7437944b388f..42ec2d1f7a61 100644 > --- a/drivers/gpu/drm/i915/intel_sdvo.c > +++ b/drivers/gpu/drm/i915/intel_sdvo.c > @@ -1429,6 +1429,8 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, > u8 val; > bool ret; > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_SDVO); > + > sdvox = I915_READ(intel_sdvo->sdvo_reg); > > ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); > diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c > index a79a7591b2cf..b18609cebe03 100644 > --- a/drivers/gpu/drm/i915/intel_tv.c > +++ b/drivers/gpu/drm/i915/intel_tv.c > @@ -868,6 +868,8 @@ static void > intel_tv_get_config(struct intel_encoder *encoder, > struct intel_crtc_state *pipe_config) > { > + pipe_config->output_types |= BIT(INTEL_OUTPUT_TVOUT); > + > pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; > } >
On Fri, Oct 27, 2017 at 02:05:38PM +0200, Maarten Lankhorst wrote: > Op 19-10-17 om 15:37 schreef Ville Syrjala: > > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > > > Currently the DDI encoder->type will change at runtime depending on > > what kind of hotplugs we've processed. That's quite bad since we can't > > really trust that that current value of encoder->type actually matches > > the type of signal we're trying to drive through it. > > > > Let's eliminate that problem by declaring that non-eDP DDI port will > > always have the encoder type as INTEL_OUTPUT_DDI. This means the code > > can no longer try to distinguish DP vs. HDMI based on encoder->type. > > We'll leave eDP as INTEL_OUTPUT_EDP, since it'll never change and > > there's a bunch of code that relies on that value to identify eDP > > encoders. > > > > We'll introduce a new encoder .compute_output_type() hook. This allows > > us to compute the full output_types before any encoder .compute_config() > > hooks get called, thus those hooks can rely on output_types being > > correct, which is useful for cloning on oldr platforms. For now we'll > > just look at the connector type and pick the correct mode based on that. > > In the future the new hook could be used to implement dynamic switching > > between LS and PCON modes for LSPCON. > > > > TODO: maybe make .get_config() populate output_types rather than doing > > the default encoder->type thing in caller and then undoing it for > > DDI in .get_config(). > > > > v2: Fix BXT/GLK PPS explosion with DSI/MST encoders > > v3: Avoid the PPS warn on pure HDMI/DVI DDI encoders by checking dp.output_reg > > v4: Rebase > > v5: Populate output_types in .get_config() rather than in the caller > > Could we get rid of compute_output_type in this patch? Perhaps do it as preliminary > patch towards removing the use? We don't want to remove it. > > Rest of the series except patch 8 looks good. For patch 1-4, 6, 7, 9 (if the delta > between ddi_get_config and old mst get_config is harmless or beneficial) and 10: > > Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> > > Thanks for the work towards cleaning this mess up. > > ~Maarten > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > > --- > > drivers/gpu/drm/i915/i915_debugfs.c | 2 +- > > drivers/gpu/drm/i915/intel_crt.c | 2 ++ > > drivers/gpu/drm/i915/intel_ddi.c | 43 ++++++++++++++++++++++++++++------- > > drivers/gpu/drm/i915/intel_display.c | 16 +++++++------ > > drivers/gpu/drm/i915/intel_dp.c | 24 +++++++++---------- > > drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++ > > drivers/gpu/drm/i915/intel_drv.h | 7 ++++-- > > drivers/gpu/drm/i915/intel_dsi.c | 2 ++ > > drivers/gpu/drm/i915/intel_dvo.c | 2 ++ > > drivers/gpu/drm/i915/intel_hdmi.c | 12 ++++------ > > drivers/gpu/drm/i915/intel_lvds.c | 2 ++ > > drivers/gpu/drm/i915/intel_opregion.c | 2 +- > > drivers/gpu/drm/i915/intel_sdvo.c | 2 ++ > > drivers/gpu/drm/i915/intel_tv.c | 2 ++ > > 14 files changed, 80 insertions(+), 40 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c > > index c65e381b85f3..e5333bfdf32d 100644 > > --- a/drivers/gpu/drm/i915/i915_debugfs.c > > +++ b/drivers/gpu/drm/i915/i915_debugfs.c > > @@ -3049,7 +3049,7 @@ static void intel_connector_info(struct seq_file *m, > > break; > > case DRM_MODE_CONNECTOR_HDMIA: > > if (intel_encoder->type == INTEL_OUTPUT_HDMI || > > - intel_encoder->type == INTEL_OUTPUT_UNKNOWN) > > + intel_encoder->type == INTEL_OUTPUT_DDI) > > intel_hdmi_info(m, intel_connector); > > break; > > default: > > diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c > > index 668e8c3e791d..a61e61efe9aa 100644 > > --- a/drivers/gpu/drm/i915/intel_crt.c > > +++ b/drivers/gpu/drm/i915/intel_crt.c > > @@ -119,6 +119,8 @@ static unsigned int intel_crt_get_flags(struct intel_encoder *encoder) > > static void intel_crt_get_config(struct intel_encoder *encoder, > > struct intel_crtc_state *pipe_config) > > { > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); > > + > > pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder); > > > > pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c > > index c8790bb74839..630609575db4 100644 > > --- a/drivers/gpu/drm/i915/intel_ddi.c > > +++ b/drivers/gpu/drm/i915/intel_ddi.c > > @@ -497,10 +497,8 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *encoder) > > switch (encoder->type) { > > case INTEL_OUTPUT_DP_MST: > > return enc_to_mst(&encoder->base)->primary->port; > > - case INTEL_OUTPUT_DP: > > case INTEL_OUTPUT_EDP: > > - case INTEL_OUTPUT_HDMI: > > - case INTEL_OUTPUT_UNKNOWN: > > + case INTEL_OUTPUT_DDI: > > return enc_to_dig_port(&encoder->base)->port; > > case INTEL_OUTPUT_ANALOG: > > return PORT_E; > > @@ -1532,6 +1530,7 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, > > struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > > enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; > > uint32_t temp; > > + > > temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); > > if (state == true) > > temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC; > > @@ -2586,12 +2585,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder, > > pipe_config->hdmi_high_tmds_clock_ratio = true; > > /* fall through */ > > case TRANS_DDI_MODE_SELECT_DVI: > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); > > pipe_config->lane_count = 4; > > break; > > case TRANS_DDI_MODE_SELECT_FDI: > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); > > break; > > case TRANS_DDI_MODE_SELECT_DP_SST: > > + if (encoder->type == INTEL_OUTPUT_EDP) > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); > > + else > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); > > + pipe_config->lane_count = > > + ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; > > + intel_dp_get_m_n(intel_crtc, pipe_config); > > + break; > > case TRANS_DDI_MODE_SELECT_DP_MST: > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); > > pipe_config->lane_count = > > ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; > > intel_dp_get_m_n(intel_crtc, pipe_config); > > @@ -2630,21 +2640,36 @@ void intel_ddi_get_config(struct intel_encoder *encoder, > > bxt_ddi_phy_get_lane_lat_optim_mask(encoder); > > } > > > > +static enum intel_output_type > > +intel_ddi_compute_output_type(struct intel_encoder *encoder, > > + struct intel_crtc_state *crtc_state, > > + struct drm_connector_state *conn_state) > > +{ > > + switch (conn_state->connector->connector_type) { > > + case DRM_MODE_CONNECTOR_HDMIA: > > + return INTEL_OUTPUT_HDMI; > > + case DRM_MODE_CONNECTOR_eDP: > > + return INTEL_OUTPUT_EDP; > > + case DRM_MODE_CONNECTOR_DisplayPort: > > + return INTEL_OUTPUT_DP; > > + default: > > + MISSING_CASE(conn_state->connector->connector_type); > > + return INTEL_OUTPUT_UNUSED; > > + } > > +} > > + > > static bool intel_ddi_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); > > - int type = encoder->type; > > int port = intel_ddi_get_encoder_port(encoder); > > int ret; > > > > - WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); > > - > > if (port == PORT_A) > > pipe_config->cpu_transcoder = TRANSCODER_EDP; > > > > - if (type == INTEL_OUTPUT_HDMI) > > + if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) > > ret = intel_hdmi_compute_config(encoder, pipe_config, conn_state); > > else > > ret = intel_dp_compute_config(encoder, pipe_config, conn_state); > > @@ -2764,6 +2789,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) > > drm_encoder_init(&dev_priv->drm, encoder, &intel_ddi_funcs, > > DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port)); > > > > + intel_encoder->compute_output_type = intel_ddi_compute_output_type; > > intel_encoder->compute_config = intel_ddi_compute_config; > > intel_encoder->enable = intel_enable_ddi; > > if (IS_GEN9_LP(dev_priv)) > > @@ -2821,9 +2847,10 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) > > } > > } > > > > + intel_dig_port->dp.output_reg = INVALID_MMIO_REG; > > intel_dig_port->max_lanes = max_lanes; > > > > - intel_encoder->type = INTEL_OUTPUT_UNKNOWN; > > + intel_encoder->type = INTEL_OUTPUT_DDI; > > intel_encoder->power_domain = intel_port_to_power_domain(port); > > intel_encoder->port = port; > > intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > > index bd62c0a65bcd..a7e02ae33583 100644 > > --- a/drivers/gpu/drm/i915/intel_display.c > > +++ b/drivers/gpu/drm/i915/intel_display.c > > @@ -10591,7 +10591,7 @@ static const char * const output_type_str[] = { > > OUTPUT_TYPE(DP), > > OUTPUT_TYPE(EDP), > > OUTPUT_TYPE(DSI), > > - OUTPUT_TYPE(UNKNOWN), > > + OUTPUT_TYPE(DDI), > > OUTPUT_TYPE(DP_MST), > > }; > > > > @@ -10762,7 +10762,7 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state) > > > > switch (encoder->type) { > > unsigned int port_mask; > > - case INTEL_OUTPUT_UNKNOWN: > > + case INTEL_OUTPUT_DDI: > > if (WARN_ON(!HAS_DDI(to_i915(dev)))) > > break; > > case INTEL_OUTPUT_DP: > > @@ -10895,7 +10895,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, > > * Determine output_types before calling the .compute_config() > > * hooks so that the hooks can use this information safely. > > */ > > - pipe_config->output_types |= 1 << encoder->type; > > + if (encoder->compute_output_type) > > + pipe_config->output_types |= > > + BIT(encoder->compute_output_type(encoder, pipe_config, > > + connector_state)); > > + else > > + pipe_config->output_types |= BIT(encoder->type); > > } > > > > encoder_retry: > > @@ -11572,10 +11577,8 @@ verify_crtc_state(struct drm_crtc *crtc, > > "Encoder connected to wrong pipe %c\n", > > pipe_name(pipe)); > > > > - if (active) { > > - pipe_config->output_types |= 1 << encoder->type; > > + if (active) > > encoder->get_config(encoder, pipe_config); > > - } > > } > > > > intel_crtc_compute_pixel_rate(pipe_config); > > @@ -14963,7 +14966,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) > > crtc_state = to_intel_crtc_state(crtc->base.state); > > > > encoder->base.crtc = &crtc->base; > > - crtc_state->output_types |= 1 << encoder->type; > > encoder->get_config(encoder, crtc_state); > > } else { > > encoder->base.crtc = NULL; > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > > index aa75f55eeb61..2b482d12000e 100644 > > --- a/drivers/gpu/drm/i915/intel_dp.c > > +++ b/drivers/gpu/drm/i915/intel_dp.c > > @@ -758,11 +758,16 @@ void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) > > struct intel_dp *intel_dp; > > > > if (encoder->type != INTEL_OUTPUT_DP && > > - encoder->type != INTEL_OUTPUT_EDP) > > + encoder->type != INTEL_OUTPUT_EDP && > > + encoder->type != INTEL_OUTPUT_DDI) > > continue; > > > > intel_dp = enc_to_intel_dp(&encoder->base); > > > > + /* Skip pure DVI/HDMI DDI encoders */ > > + if (!i915_mmio_reg_valid(intel_dp->output_reg)) > > + continue; > > + > > WARN_ON(intel_dp->active_pipe != INVALID_PIPE); > > > > if (encoder->type != INTEL_OUTPUT_EDP) > > @@ -2603,6 +2608,11 @@ static void intel_dp_get_config(struct intel_encoder *encoder, > > enum port port = dp_to_dig_port(intel_dp)->port; > > struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); > > > > + if (encoder->type == INTEL_OUTPUT_EDP) > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); > > + else > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); > > + > > tmp = I915_READ(intel_dp->output_reg); > > > > pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A; > > @@ -4699,8 +4709,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) > > { > > struct drm_connector *connector = &intel_connector->base; > > struct intel_dp *intel_dp = intel_attached_dp(connector); > > - struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); > > - struct intel_encoder *intel_encoder = &intel_dig_port->base; > > struct drm_device *dev = connector->dev; > > enum drm_connector_status status; > > u8 sink_irq_vector = 0; > > @@ -4733,9 +4741,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) > > goto out; > > } > > > > - if (intel_encoder->type != INTEL_OUTPUT_EDP) > > - intel_encoder->type = INTEL_OUTPUT_DP; > > - > > if (intel_dp->reset_link_params) { > > /* Initial max link lane count */ > > intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); > > @@ -4852,9 +4857,6 @@ intel_dp_force(struct drm_connector *connector) > > intel_dp_set_edid(intel_dp); > > > > intel_display_power_put(dev_priv, intel_dp->aux_power_domain); > > - > > - if (intel_encoder->type != INTEL_OUTPUT_EDP) > > - intel_encoder->type = INTEL_OUTPUT_DP; > > } > > > > static int intel_dp_get_modes(struct drm_connector *connector) > > @@ -5073,10 +5075,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) > > struct drm_i915_private *dev_priv = to_i915(dev); > > enum irqreturn ret = IRQ_NONE; > > > > - if (intel_dig_port->base.type != INTEL_OUTPUT_EDP && > > - intel_dig_port->base.type != INTEL_OUTPUT_HDMI) > > - intel_dig_port->base.type = INTEL_OUTPUT_DP; > > - > > if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { > > /* > > * vdd off can generate a long pulse on eDP which > > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c > > index 772521440a9f..9be6f32bb100 100644 > > --- a/drivers/gpu/drm/i915/intel_dp_mst.c > > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c > > @@ -270,6 +270,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, > > enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; > > u32 temp, flags = 0; > > > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); > > + > > pipe_config->has_audio = > > intel_ddi_is_audio_enabled(dev_priv, crtc); > > > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > > index a05ab3a1ab27..650129980ce2 100644 > > --- a/drivers/gpu/drm/i915/intel_drv.h > > +++ b/drivers/gpu/drm/i915/intel_drv.h > > @@ -173,7 +173,7 @@ enum intel_output_type { > > INTEL_OUTPUT_DP = 7, > > INTEL_OUTPUT_EDP = 8, > > INTEL_OUTPUT_DSI = 9, > > - INTEL_OUTPUT_UNKNOWN = 10, > > + INTEL_OUTPUT_DDI = 10, > > INTEL_OUTPUT_DP_MST = 11, > > }; > > > > @@ -216,6 +216,9 @@ struct intel_encoder { > > enum port port; > > unsigned int cloneable; > > void (*hot_plug)(struct intel_encoder *); > > + enum intel_output_type (*compute_output_type)(struct intel_encoder *, > > + struct intel_crtc_state *, > > + struct drm_connector_state *); > > bool (*compute_config)(struct intel_encoder *, > > struct intel_crtc_state *, > > struct drm_connector_state *); > > @@ -1149,7 +1152,7 @@ enc_to_dig_port(struct drm_encoder *encoder) > > struct intel_encoder *intel_encoder = to_intel_encoder(encoder); > > > > switch (intel_encoder->type) { > > - case INTEL_OUTPUT_UNKNOWN: > > + case INTEL_OUTPUT_DDI: > > WARN_ON(!HAS_DDI(to_i915(encoder->dev))); > > case INTEL_OUTPUT_DP: > > case INTEL_OUTPUT_EDP: > > diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c > > index 66bbedc5fa01..2ae3eea19317 100644 > > --- a/drivers/gpu/drm/i915/intel_dsi.c > > +++ b/drivers/gpu/drm/i915/intel_dsi.c > > @@ -1243,6 +1243,8 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, > > u32 pclk; > > DRM_DEBUG_KMS("\n"); > > > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI); > > + > > if (IS_GEN9_LP(dev_priv)) > > bxt_dsi_get_pipe_config(encoder, pipe_config); > > > > diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c > > index 53c9b763f4ce..754baa00bea9 100644 > > --- a/drivers/gpu/drm/i915/intel_dvo.c > > +++ b/drivers/gpu/drm/i915/intel_dvo.c > > @@ -159,6 +159,8 @@ static void intel_dvo_get_config(struct intel_encoder *encoder, > > struct intel_dvo *intel_dvo = enc_to_dvo(encoder); > > u32 tmp, flags = 0; > > > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DVO); > > + > > tmp = I915_READ(intel_dvo->dev.dvo_reg); > > if (tmp & DVO_HSYNC_ACTIVE_HIGH) > > flags |= DRM_MODE_FLAG_PHSYNC; > > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > > index 5132dc814788..1ff448a67b99 100644 > > --- a/drivers/gpu/drm/i915/intel_hdmi.c > > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > > @@ -957,6 +957,8 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, > > u32 tmp, flags = 0; > > int dotclock; > > > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); > > + > > tmp = I915_READ(intel_hdmi->hdmi_reg); > > > > if (tmp & SDVO_HSYNC_ACTIVE_HIGH) > > @@ -1610,12 +1612,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) > > > > intel_hdmi_unset_edid(connector); > > > > - if (intel_hdmi_set_edid(connector)) { > > - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > > - > > - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; > > + if (intel_hdmi_set_edid(connector)) > > status = connector_status_connected; > > - } else > > + else > > status = connector_status_disconnected; > > > > intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); > > @@ -1626,8 +1625,6 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) > > static void > > intel_hdmi_force(struct drm_connector *connector) > > { > > - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > > - > > DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", > > connector->base.id, connector->name); > > > > @@ -1637,7 +1634,6 @@ intel_hdmi_force(struct drm_connector *connector) > > return; > > > > intel_hdmi_set_edid(connector); > > - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; > > } > > > > static int intel_hdmi_get_modes(struct drm_connector *connector) > > diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c > > index 38572d65e46e..ef80499113ee 100644 > > --- a/drivers/gpu/drm/i915/intel_lvds.c > > +++ b/drivers/gpu/drm/i915/intel_lvds.c > > @@ -125,6 +125,8 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, > > struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); > > u32 tmp, flags = 0; > > > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_LVDS); > > + > > tmp = I915_READ(lvds_encoder->reg); > > if (tmp & LVDS_HSYNC_POLARITY) > > flags |= DRM_MODE_FLAG_NHSYNC; > > diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c > > index 1d946240e55f..39714be3eb6b 100644 > > --- a/drivers/gpu/drm/i915/intel_opregion.c > > +++ b/drivers/gpu/drm/i915/intel_opregion.c > > @@ -383,7 +383,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, > > case INTEL_OUTPUT_ANALOG: > > type = DISPLAY_TYPE_CRT; > > break; > > - case INTEL_OUTPUT_UNKNOWN: > > + case INTEL_OUTPUT_DDI: > > case INTEL_OUTPUT_DP: > > case INTEL_OUTPUT_HDMI: > > case INTEL_OUTPUT_DP_MST: > > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c > > index 7437944b388f..42ec2d1f7a61 100644 > > --- a/drivers/gpu/drm/i915/intel_sdvo.c > > +++ b/drivers/gpu/drm/i915/intel_sdvo.c > > @@ -1429,6 +1429,8 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, > > u8 val; > > bool ret; > > > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_SDVO); > > + > > sdvox = I915_READ(intel_sdvo->sdvo_reg); > > > > ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); > > diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c > > index a79a7591b2cf..b18609cebe03 100644 > > --- a/drivers/gpu/drm/i915/intel_tv.c > > +++ b/drivers/gpu/drm/i915/intel_tv.c > > @@ -868,6 +868,8 @@ static void > > intel_tv_get_config(struct intel_encoder *encoder, > > struct intel_crtc_state *pipe_config) > > { > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_TVOUT); > > + > > pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; > > } > > >
Op 27-10-17 om 14:44 schreef Ville Syrjälä: > On Fri, Oct 27, 2017 at 02:05:38PM +0200, Maarten Lankhorst wrote: >> Op 19-10-17 om 15:37 schreef Ville Syrjala: >>> From: Ville Syrjälä <ville.syrjala@linux.intel.com> >>> >>> Currently the DDI encoder->type will change at runtime depending on >>> what kind of hotplugs we've processed. That's quite bad since we can't >>> really trust that that current value of encoder->type actually matches >>> the type of signal we're trying to drive through it. >>> >>> Let's eliminate that problem by declaring that non-eDP DDI port will >>> always have the encoder type as INTEL_OUTPUT_DDI. This means the code >>> can no longer try to distinguish DP vs. HDMI based on encoder->type. >>> We'll leave eDP as INTEL_OUTPUT_EDP, since it'll never change and >>> there's a bunch of code that relies on that value to identify eDP >>> encoders. >>> >>> We'll introduce a new encoder .compute_output_type() hook. This allows >>> us to compute the full output_types before any encoder .compute_config() >>> hooks get called, thus those hooks can rely on output_types being >>> correct, which is useful for cloning on oldr platforms. For now we'll >>> just look at the connector type and pick the correct mode based on that. >>> In the future the new hook could be used to implement dynamic switching >>> between LS and PCON modes for LSPCON. >>> >>> TODO: maybe make .get_config() populate output_types rather than doing >>> the default encoder->type thing in caller and then undoing it for >>> DDI in .get_config(). >>> >>> v2: Fix BXT/GLK PPS explosion with DSI/MST encoders >>> v3: Avoid the PPS warn on pure HDMI/DVI DDI encoders by checking dp.output_reg >>> v4: Rebase >>> v5: Populate output_types in .get_config() rather than in the caller >> Could we get rid of compute_output_type in this patch? Perhaps do it as preliminary >> patch towards removing the use? > We don't want to remove it. Ok, but could that still be a separate preparation patch? That would make it easier to review. :) >> Rest of the series except patch 8 looks good. For patch 1-4, 6, 7, 9 (if the delta >> between ddi_get_config and old mst get_config is harmless or beneficial) and 10: >> >> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> >> >> Thanks for the work towards cleaning this mess up. >> >> ~Maarten >>> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> >>> --- >>> drivers/gpu/drm/i915/i915_debugfs.c | 2 +- >>> drivers/gpu/drm/i915/intel_crt.c | 2 ++ >>> drivers/gpu/drm/i915/intel_ddi.c | 43 ++++++++++++++++++++++++++++------- >>> drivers/gpu/drm/i915/intel_display.c | 16 +++++++------ >>> drivers/gpu/drm/i915/intel_dp.c | 24 +++++++++---------- >>> drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++ >>> drivers/gpu/drm/i915/intel_drv.h | 7 ++++-- >>> drivers/gpu/drm/i915/intel_dsi.c | 2 ++ >>> drivers/gpu/drm/i915/intel_dvo.c | 2 ++ >>> drivers/gpu/drm/i915/intel_hdmi.c | 12 ++++------ >>> drivers/gpu/drm/i915/intel_lvds.c | 2 ++ >>> drivers/gpu/drm/i915/intel_opregion.c | 2 +- >>> drivers/gpu/drm/i915/intel_sdvo.c | 2 ++ >>> drivers/gpu/drm/i915/intel_tv.c | 2 ++ >>> 14 files changed, 80 insertions(+), 40 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c >>> index c65e381b85f3..e5333bfdf32d 100644 >>> --- a/drivers/gpu/drm/i915/i915_debugfs.c >>> +++ b/drivers/gpu/drm/i915/i915_debugfs.c >>> @@ -3049,7 +3049,7 @@ static void intel_connector_info(struct seq_file *m, >>> break; >>> case DRM_MODE_CONNECTOR_HDMIA: >>> if (intel_encoder->type == INTEL_OUTPUT_HDMI || >>> - intel_encoder->type == INTEL_OUTPUT_UNKNOWN) >>> + intel_encoder->type == INTEL_OUTPUT_DDI) >>> intel_hdmi_info(m, intel_connector); >>> break; >>> default: >>> diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c >>> index 668e8c3e791d..a61e61efe9aa 100644 >>> --- a/drivers/gpu/drm/i915/intel_crt.c >>> +++ b/drivers/gpu/drm/i915/intel_crt.c >>> @@ -119,6 +119,8 @@ static unsigned int intel_crt_get_flags(struct intel_encoder *encoder) >>> static void intel_crt_get_config(struct intel_encoder *encoder, >>> struct intel_crtc_state *pipe_config) >>> { >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); >>> + >>> pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder); >>> >>> pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; >>> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c >>> index c8790bb74839..630609575db4 100644 >>> --- a/drivers/gpu/drm/i915/intel_ddi.c >>> +++ b/drivers/gpu/drm/i915/intel_ddi.c >>> @@ -497,10 +497,8 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *encoder) >>> switch (encoder->type) { >>> case INTEL_OUTPUT_DP_MST: >>> return enc_to_mst(&encoder->base)->primary->port; >>> - case INTEL_OUTPUT_DP: >>> case INTEL_OUTPUT_EDP: >>> - case INTEL_OUTPUT_HDMI: >>> - case INTEL_OUTPUT_UNKNOWN: >>> + case INTEL_OUTPUT_DDI: >>> return enc_to_dig_port(&encoder->base)->port; >>> case INTEL_OUTPUT_ANALOG: >>> return PORT_E; >>> @@ -1532,6 +1530,7 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, >>> struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); >>> enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; >>> uint32_t temp; >>> + >>> temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); >>> if (state == true) >>> temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC; >>> @@ -2586,12 +2585,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder, >>> pipe_config->hdmi_high_tmds_clock_ratio = true; >>> /* fall through */ >>> case TRANS_DDI_MODE_SELECT_DVI: >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); >>> pipe_config->lane_count = 4; >>> break; >>> case TRANS_DDI_MODE_SELECT_FDI: >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); >>> break; >>> case TRANS_DDI_MODE_SELECT_DP_SST: >>> + if (encoder->type == INTEL_OUTPUT_EDP) >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); >>> + else >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); >>> + pipe_config->lane_count = >>> + ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; >>> + intel_dp_get_m_n(intel_crtc, pipe_config); >>> + break; >>> case TRANS_DDI_MODE_SELECT_DP_MST: >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); >>> pipe_config->lane_count = >>> ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; >>> intel_dp_get_m_n(intel_crtc, pipe_config); >>> @@ -2630,21 +2640,36 @@ void intel_ddi_get_config(struct intel_encoder *encoder, >>> bxt_ddi_phy_get_lane_lat_optim_mask(encoder); >>> } >>> >>> +static enum intel_output_type >>> +intel_ddi_compute_output_type(struct intel_encoder *encoder, >>> + struct intel_crtc_state *crtc_state, >>> + struct drm_connector_state *conn_state) >>> +{ >>> + switch (conn_state->connector->connector_type) { >>> + case DRM_MODE_CONNECTOR_HDMIA: >>> + return INTEL_OUTPUT_HDMI; >>> + case DRM_MODE_CONNECTOR_eDP: >>> + return INTEL_OUTPUT_EDP; >>> + case DRM_MODE_CONNECTOR_DisplayPort: >>> + return INTEL_OUTPUT_DP; >>> + default: >>> + MISSING_CASE(conn_state->connector->connector_type); >>> + return INTEL_OUTPUT_UNUSED; >>> + } >>> +} >>> + >>> static bool intel_ddi_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); >>> - int type = encoder->type; >>> int port = intel_ddi_get_encoder_port(encoder); >>> int ret; >>> >>> - WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); >>> - >>> if (port == PORT_A) >>> pipe_config->cpu_transcoder = TRANSCODER_EDP; >>> >>> - if (type == INTEL_OUTPUT_HDMI) >>> + if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) >>> ret = intel_hdmi_compute_config(encoder, pipe_config, conn_state); >>> else >>> ret = intel_dp_compute_config(encoder, pipe_config, conn_state); >>> @@ -2764,6 +2789,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) >>> drm_encoder_init(&dev_priv->drm, encoder, &intel_ddi_funcs, >>> DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port)); >>> >>> + intel_encoder->compute_output_type = intel_ddi_compute_output_type; >>> intel_encoder->compute_config = intel_ddi_compute_config; >>> intel_encoder->enable = intel_enable_ddi; >>> if (IS_GEN9_LP(dev_priv)) >>> @@ -2821,9 +2847,10 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) >>> } >>> } >>> >>> + intel_dig_port->dp.output_reg = INVALID_MMIO_REG; >>> intel_dig_port->max_lanes = max_lanes; >>> >>> - intel_encoder->type = INTEL_OUTPUT_UNKNOWN; >>> + intel_encoder->type = INTEL_OUTPUT_DDI; >>> intel_encoder->power_domain = intel_port_to_power_domain(port); >>> intel_encoder->port = port; >>> intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); >>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c >>> index bd62c0a65bcd..a7e02ae33583 100644 >>> --- a/drivers/gpu/drm/i915/intel_display.c >>> +++ b/drivers/gpu/drm/i915/intel_display.c >>> @@ -10591,7 +10591,7 @@ static const char * const output_type_str[] = { >>> OUTPUT_TYPE(DP), >>> OUTPUT_TYPE(EDP), >>> OUTPUT_TYPE(DSI), >>> - OUTPUT_TYPE(UNKNOWN), >>> + OUTPUT_TYPE(DDI), >>> OUTPUT_TYPE(DP_MST), >>> }; >>> >>> @@ -10762,7 +10762,7 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state) >>> >>> switch (encoder->type) { >>> unsigned int port_mask; >>> - case INTEL_OUTPUT_UNKNOWN: >>> + case INTEL_OUTPUT_DDI: >>> if (WARN_ON(!HAS_DDI(to_i915(dev)))) >>> break; >>> case INTEL_OUTPUT_DP: >>> @@ -10895,7 +10895,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, >>> * Determine output_types before calling the .compute_config() >>> * hooks so that the hooks can use this information safely. >>> */ >>> - pipe_config->output_types |= 1 << encoder->type; >>> + if (encoder->compute_output_type) >>> + pipe_config->output_types |= >>> + BIT(encoder->compute_output_type(encoder, pipe_config, >>> + connector_state)); >>> + else >>> + pipe_config->output_types |= BIT(encoder->type); >>> } >>> >>> encoder_retry: >>> @@ -11572,10 +11577,8 @@ verify_crtc_state(struct drm_crtc *crtc, >>> "Encoder connected to wrong pipe %c\n", >>> pipe_name(pipe)); >>> >>> - if (active) { >>> - pipe_config->output_types |= 1 << encoder->type; >>> + if (active) >>> encoder->get_config(encoder, pipe_config); >>> - } >>> } >>> >>> intel_crtc_compute_pixel_rate(pipe_config); >>> @@ -14963,7 +14966,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) >>> crtc_state = to_intel_crtc_state(crtc->base.state); >>> >>> encoder->base.crtc = &crtc->base; >>> - crtc_state->output_types |= 1 << encoder->type; >>> encoder->get_config(encoder, crtc_state); >>> } else { >>> encoder->base.crtc = NULL; >>> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c >>> index aa75f55eeb61..2b482d12000e 100644 >>> --- a/drivers/gpu/drm/i915/intel_dp.c >>> +++ b/drivers/gpu/drm/i915/intel_dp.c >>> @@ -758,11 +758,16 @@ void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) >>> struct intel_dp *intel_dp; >>> >>> if (encoder->type != INTEL_OUTPUT_DP && >>> - encoder->type != INTEL_OUTPUT_EDP) >>> + encoder->type != INTEL_OUTPUT_EDP && >>> + encoder->type != INTEL_OUTPUT_DDI) >>> continue; >>> >>> intel_dp = enc_to_intel_dp(&encoder->base); >>> >>> + /* Skip pure DVI/HDMI DDI encoders */ >>> + if (!i915_mmio_reg_valid(intel_dp->output_reg)) >>> + continue; >>> + >>> WARN_ON(intel_dp->active_pipe != INVALID_PIPE); >>> >>> if (encoder->type != INTEL_OUTPUT_EDP) >>> @@ -2603,6 +2608,11 @@ static void intel_dp_get_config(struct intel_encoder *encoder, >>> enum port port = dp_to_dig_port(intel_dp)->port; >>> struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); >>> >>> + if (encoder->type == INTEL_OUTPUT_EDP) >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); >>> + else >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); >>> + >>> tmp = I915_READ(intel_dp->output_reg); >>> >>> pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A; >>> @@ -4699,8 +4709,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) >>> { >>> struct drm_connector *connector = &intel_connector->base; >>> struct intel_dp *intel_dp = intel_attached_dp(connector); >>> - struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); >>> - struct intel_encoder *intel_encoder = &intel_dig_port->base; >>> struct drm_device *dev = connector->dev; >>> enum drm_connector_status status; >>> u8 sink_irq_vector = 0; >>> @@ -4733,9 +4741,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) >>> goto out; >>> } >>> >>> - if (intel_encoder->type != INTEL_OUTPUT_EDP) >>> - intel_encoder->type = INTEL_OUTPUT_DP; >>> - >>> if (intel_dp->reset_link_params) { >>> /* Initial max link lane count */ >>> intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); >>> @@ -4852,9 +4857,6 @@ intel_dp_force(struct drm_connector *connector) >>> intel_dp_set_edid(intel_dp); >>> >>> intel_display_power_put(dev_priv, intel_dp->aux_power_domain); >>> - >>> - if (intel_encoder->type != INTEL_OUTPUT_EDP) >>> - intel_encoder->type = INTEL_OUTPUT_DP; >>> } >>> >>> static int intel_dp_get_modes(struct drm_connector *connector) >>> @@ -5073,10 +5075,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) >>> struct drm_i915_private *dev_priv = to_i915(dev); >>> enum irqreturn ret = IRQ_NONE; >>> >>> - if (intel_dig_port->base.type != INTEL_OUTPUT_EDP && >>> - intel_dig_port->base.type != INTEL_OUTPUT_HDMI) >>> - intel_dig_port->base.type = INTEL_OUTPUT_DP; >>> - >>> if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { >>> /* >>> * vdd off can generate a long pulse on eDP which >>> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c >>> index 772521440a9f..9be6f32bb100 100644 >>> --- a/drivers/gpu/drm/i915/intel_dp_mst.c >>> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c >>> @@ -270,6 +270,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, >>> enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; >>> u32 temp, flags = 0; >>> >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); >>> + >>> pipe_config->has_audio = >>> intel_ddi_is_audio_enabled(dev_priv, crtc); >>> >>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h >>> index a05ab3a1ab27..650129980ce2 100644 >>> --- a/drivers/gpu/drm/i915/intel_drv.h >>> +++ b/drivers/gpu/drm/i915/intel_drv.h >>> @@ -173,7 +173,7 @@ enum intel_output_type { >>> INTEL_OUTPUT_DP = 7, >>> INTEL_OUTPUT_EDP = 8, >>> INTEL_OUTPUT_DSI = 9, >>> - INTEL_OUTPUT_UNKNOWN = 10, >>> + INTEL_OUTPUT_DDI = 10, >>> INTEL_OUTPUT_DP_MST = 11, >>> }; >>> >>> @@ -216,6 +216,9 @@ struct intel_encoder { >>> enum port port; >>> unsigned int cloneable; >>> void (*hot_plug)(struct intel_encoder *); >>> + enum intel_output_type (*compute_output_type)(struct intel_encoder *, >>> + struct intel_crtc_state *, >>> + struct drm_connector_state *); >>> bool (*compute_config)(struct intel_encoder *, >>> struct intel_crtc_state *, >>> struct drm_connector_state *); >>> @@ -1149,7 +1152,7 @@ enc_to_dig_port(struct drm_encoder *encoder) >>> struct intel_encoder *intel_encoder = to_intel_encoder(encoder); >>> >>> switch (intel_encoder->type) { >>> - case INTEL_OUTPUT_UNKNOWN: >>> + case INTEL_OUTPUT_DDI: >>> WARN_ON(!HAS_DDI(to_i915(encoder->dev))); >>> case INTEL_OUTPUT_DP: >>> case INTEL_OUTPUT_EDP: >>> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c >>> index 66bbedc5fa01..2ae3eea19317 100644 >>> --- a/drivers/gpu/drm/i915/intel_dsi.c >>> +++ b/drivers/gpu/drm/i915/intel_dsi.c >>> @@ -1243,6 +1243,8 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, >>> u32 pclk; >>> DRM_DEBUG_KMS("\n"); >>> >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI); >>> + >>> if (IS_GEN9_LP(dev_priv)) >>> bxt_dsi_get_pipe_config(encoder, pipe_config); >>> >>> diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c >>> index 53c9b763f4ce..754baa00bea9 100644 >>> --- a/drivers/gpu/drm/i915/intel_dvo.c >>> +++ b/drivers/gpu/drm/i915/intel_dvo.c >>> @@ -159,6 +159,8 @@ static void intel_dvo_get_config(struct intel_encoder *encoder, >>> struct intel_dvo *intel_dvo = enc_to_dvo(encoder); >>> u32 tmp, flags = 0; >>> >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_DVO); >>> + >>> tmp = I915_READ(intel_dvo->dev.dvo_reg); >>> if (tmp & DVO_HSYNC_ACTIVE_HIGH) >>> flags |= DRM_MODE_FLAG_PHSYNC; >>> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c >>> index 5132dc814788..1ff448a67b99 100644 >>> --- a/drivers/gpu/drm/i915/intel_hdmi.c >>> +++ b/drivers/gpu/drm/i915/intel_hdmi.c >>> @@ -957,6 +957,8 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, >>> u32 tmp, flags = 0; >>> int dotclock; >>> >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); >>> + >>> tmp = I915_READ(intel_hdmi->hdmi_reg); >>> >>> if (tmp & SDVO_HSYNC_ACTIVE_HIGH) >>> @@ -1610,12 +1612,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) >>> >>> intel_hdmi_unset_edid(connector); >>> >>> - if (intel_hdmi_set_edid(connector)) { >>> - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); >>> - >>> - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; >>> + if (intel_hdmi_set_edid(connector)) >>> status = connector_status_connected; >>> - } else >>> + else >>> status = connector_status_disconnected; >>> >>> intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); >>> @@ -1626,8 +1625,6 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) >>> static void >>> intel_hdmi_force(struct drm_connector *connector) >>> { >>> - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); >>> - >>> DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", >>> connector->base.id, connector->name); >>> >>> @@ -1637,7 +1634,6 @@ intel_hdmi_force(struct drm_connector *connector) >>> return; >>> >>> intel_hdmi_set_edid(connector); >>> - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; >>> } >>> >>> static int intel_hdmi_get_modes(struct drm_connector *connector) >>> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c >>> index 38572d65e46e..ef80499113ee 100644 >>> --- a/drivers/gpu/drm/i915/intel_lvds.c >>> +++ b/drivers/gpu/drm/i915/intel_lvds.c >>> @@ -125,6 +125,8 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, >>> struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); >>> u32 tmp, flags = 0; >>> >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_LVDS); >>> + >>> tmp = I915_READ(lvds_encoder->reg); >>> if (tmp & LVDS_HSYNC_POLARITY) >>> flags |= DRM_MODE_FLAG_NHSYNC; >>> diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c >>> index 1d946240e55f..39714be3eb6b 100644 >>> --- a/drivers/gpu/drm/i915/intel_opregion.c >>> +++ b/drivers/gpu/drm/i915/intel_opregion.c >>> @@ -383,7 +383,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, >>> case INTEL_OUTPUT_ANALOG: >>> type = DISPLAY_TYPE_CRT; >>> break; >>> - case INTEL_OUTPUT_UNKNOWN: >>> + case INTEL_OUTPUT_DDI: >>> case INTEL_OUTPUT_DP: >>> case INTEL_OUTPUT_HDMI: >>> case INTEL_OUTPUT_DP_MST: >>> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c >>> index 7437944b388f..42ec2d1f7a61 100644 >>> --- a/drivers/gpu/drm/i915/intel_sdvo.c >>> +++ b/drivers/gpu/drm/i915/intel_sdvo.c >>> @@ -1429,6 +1429,8 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, >>> u8 val; >>> bool ret; >>> >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_SDVO); >>> + >>> sdvox = I915_READ(intel_sdvo->sdvo_reg); >>> >>> ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); >>> diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c >>> index a79a7591b2cf..b18609cebe03 100644 >>> --- a/drivers/gpu/drm/i915/intel_tv.c >>> +++ b/drivers/gpu/drm/i915/intel_tv.c >>> @@ -868,6 +868,8 @@ static void >>> intel_tv_get_config(struct intel_encoder *encoder, >>> struct intel_crtc_state *pipe_config) >>> { >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_TVOUT); >>> + >>> pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; >>> } >>>
On Fri, Oct 27, 2017 at 03:53:34PM +0200, Maarten Lankhorst wrote: > Op 27-10-17 om 14:44 schreef Ville Syrjälä: > > On Fri, Oct 27, 2017 at 02:05:38PM +0200, Maarten Lankhorst wrote: > >> Op 19-10-17 om 15:37 schreef Ville Syrjala: > >>> From: Ville Syrjälä <ville.syrjala@linux.intel.com> > >>> > >>> Currently the DDI encoder->type will change at runtime depending on > >>> what kind of hotplugs we've processed. That's quite bad since we can't > >>> really trust that that current value of encoder->type actually matches > >>> the type of signal we're trying to drive through it. > >>> > >>> Let's eliminate that problem by declaring that non-eDP DDI port will > >>> always have the encoder type as INTEL_OUTPUT_DDI. This means the code > >>> can no longer try to distinguish DP vs. HDMI based on encoder->type. > >>> We'll leave eDP as INTEL_OUTPUT_EDP, since it'll never change and > >>> there's a bunch of code that relies on that value to identify eDP > >>> encoders. > >>> > >>> We'll introduce a new encoder .compute_output_type() hook. This allows > >>> us to compute the full output_types before any encoder .compute_config() > >>> hooks get called, thus those hooks can rely on output_types being > >>> correct, which is useful for cloning on oldr platforms. For now we'll > >>> just look at the connector type and pick the correct mode based on that. > >>> In the future the new hook could be used to implement dynamic switching > >>> between LS and PCON modes for LSPCON. > >>> > >>> TODO: maybe make .get_config() populate output_types rather than doing > >>> the default encoder->type thing in caller and then undoing it for > >>> DDI in .get_config(). > >>> > >>> v2: Fix BXT/GLK PPS explosion with DSI/MST encoders > >>> v3: Avoid the PPS warn on pure HDMI/DVI DDI encoders by checking dp.output_reg > >>> v4: Rebase > >>> v5: Populate output_types in .get_config() rather than in the caller > >> Could we get rid of compute_output_type in this patch? Perhaps do it as preliminary > >> patch towards removing the use? > > We don't want to remove it. > Ok, but could that still be a separate preparation patch? That would make it easier to review. :) Not sure which part you mean here. Moving the 'output_types |= whatever' into .get_config()? Hmm. Yeah that should be easy to split out. I guess it won't even make the DDI case any more broken that it already is since even currently encoder->type might change between the modeset compute phase and .get_config(). And it's going to be followed closely by the actual fix anyway. > >> Rest of the series except patch 8 looks good. For patch 1-4, 6, 7, 9 (if the delta > >> between ddi_get_config and old mst get_config is harmless or beneficial) and 10: > >> > >> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> > >> > >> Thanks for the work towards cleaning this mess up. > >> > >> ~Maarten > >>> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > >>> --- > >>> drivers/gpu/drm/i915/i915_debugfs.c | 2 +- > >>> drivers/gpu/drm/i915/intel_crt.c | 2 ++ > >>> drivers/gpu/drm/i915/intel_ddi.c | 43 ++++++++++++++++++++++++++++------- > >>> drivers/gpu/drm/i915/intel_display.c | 16 +++++++------ > >>> drivers/gpu/drm/i915/intel_dp.c | 24 +++++++++---------- > >>> drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++ > >>> drivers/gpu/drm/i915/intel_drv.h | 7 ++++-- > >>> drivers/gpu/drm/i915/intel_dsi.c | 2 ++ > >>> drivers/gpu/drm/i915/intel_dvo.c | 2 ++ > >>> drivers/gpu/drm/i915/intel_hdmi.c | 12 ++++------ > >>> drivers/gpu/drm/i915/intel_lvds.c | 2 ++ > >>> drivers/gpu/drm/i915/intel_opregion.c | 2 +- > >>> drivers/gpu/drm/i915/intel_sdvo.c | 2 ++ > >>> drivers/gpu/drm/i915/intel_tv.c | 2 ++ > >>> 14 files changed, 80 insertions(+), 40 deletions(-) > >>> > >>> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c > >>> index c65e381b85f3..e5333bfdf32d 100644 > >>> --- a/drivers/gpu/drm/i915/i915_debugfs.c > >>> +++ b/drivers/gpu/drm/i915/i915_debugfs.c > >>> @@ -3049,7 +3049,7 @@ static void intel_connector_info(struct seq_file *m, > >>> break; > >>> case DRM_MODE_CONNECTOR_HDMIA: > >>> if (intel_encoder->type == INTEL_OUTPUT_HDMI || > >>> - intel_encoder->type == INTEL_OUTPUT_UNKNOWN) > >>> + intel_encoder->type == INTEL_OUTPUT_DDI) > >>> intel_hdmi_info(m, intel_connector); > >>> break; > >>> default: > >>> diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c > >>> index 668e8c3e791d..a61e61efe9aa 100644 > >>> --- a/drivers/gpu/drm/i915/intel_crt.c > >>> +++ b/drivers/gpu/drm/i915/intel_crt.c > >>> @@ -119,6 +119,8 @@ static unsigned int intel_crt_get_flags(struct intel_encoder *encoder) > >>> static void intel_crt_get_config(struct intel_encoder *encoder, > >>> struct intel_crtc_state *pipe_config) > >>> { > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); > >>> + > >>> pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder); > >>> > >>> pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; > >>> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c > >>> index c8790bb74839..630609575db4 100644 > >>> --- a/drivers/gpu/drm/i915/intel_ddi.c > >>> +++ b/drivers/gpu/drm/i915/intel_ddi.c > >>> @@ -497,10 +497,8 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *encoder) > >>> switch (encoder->type) { > >>> case INTEL_OUTPUT_DP_MST: > >>> return enc_to_mst(&encoder->base)->primary->port; > >>> - case INTEL_OUTPUT_DP: > >>> case INTEL_OUTPUT_EDP: > >>> - case INTEL_OUTPUT_HDMI: > >>> - case INTEL_OUTPUT_UNKNOWN: > >>> + case INTEL_OUTPUT_DDI: > >>> return enc_to_dig_port(&encoder->base)->port; > >>> case INTEL_OUTPUT_ANALOG: > >>> return PORT_E; > >>> @@ -1532,6 +1530,7 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, > >>> struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > >>> enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; > >>> uint32_t temp; > >>> + > >>> temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); > >>> if (state == true) > >>> temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC; > >>> @@ -2586,12 +2585,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder, > >>> pipe_config->hdmi_high_tmds_clock_ratio = true; > >>> /* fall through */ > >>> case TRANS_DDI_MODE_SELECT_DVI: > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); > >>> pipe_config->lane_count = 4; > >>> break; > >>> case TRANS_DDI_MODE_SELECT_FDI: > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); > >>> break; > >>> case TRANS_DDI_MODE_SELECT_DP_SST: > >>> + if (encoder->type == INTEL_OUTPUT_EDP) > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); > >>> + else > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); > >>> + pipe_config->lane_count = > >>> + ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; > >>> + intel_dp_get_m_n(intel_crtc, pipe_config); > >>> + break; > >>> case TRANS_DDI_MODE_SELECT_DP_MST: > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); > >>> pipe_config->lane_count = > >>> ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; > >>> intel_dp_get_m_n(intel_crtc, pipe_config); > >>> @@ -2630,21 +2640,36 @@ void intel_ddi_get_config(struct intel_encoder *encoder, > >>> bxt_ddi_phy_get_lane_lat_optim_mask(encoder); > >>> } > >>> > >>> +static enum intel_output_type > >>> +intel_ddi_compute_output_type(struct intel_encoder *encoder, > >>> + struct intel_crtc_state *crtc_state, > >>> + struct drm_connector_state *conn_state) > >>> +{ > >>> + switch (conn_state->connector->connector_type) { > >>> + case DRM_MODE_CONNECTOR_HDMIA: > >>> + return INTEL_OUTPUT_HDMI; > >>> + case DRM_MODE_CONNECTOR_eDP: > >>> + return INTEL_OUTPUT_EDP; > >>> + case DRM_MODE_CONNECTOR_DisplayPort: > >>> + return INTEL_OUTPUT_DP; > >>> + default: > >>> + MISSING_CASE(conn_state->connector->connector_type); > >>> + return INTEL_OUTPUT_UNUSED; > >>> + } > >>> +} > >>> + > >>> static bool intel_ddi_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); > >>> - int type = encoder->type; > >>> int port = intel_ddi_get_encoder_port(encoder); > >>> int ret; > >>> > >>> - WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); > >>> - > >>> if (port == PORT_A) > >>> pipe_config->cpu_transcoder = TRANSCODER_EDP; > >>> > >>> - if (type == INTEL_OUTPUT_HDMI) > >>> + if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) > >>> ret = intel_hdmi_compute_config(encoder, pipe_config, conn_state); > >>> else > >>> ret = intel_dp_compute_config(encoder, pipe_config, conn_state); > >>> @@ -2764,6 +2789,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) > >>> drm_encoder_init(&dev_priv->drm, encoder, &intel_ddi_funcs, > >>> DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port)); > >>> > >>> + intel_encoder->compute_output_type = intel_ddi_compute_output_type; > >>> intel_encoder->compute_config = intel_ddi_compute_config; > >>> intel_encoder->enable = intel_enable_ddi; > >>> if (IS_GEN9_LP(dev_priv)) > >>> @@ -2821,9 +2847,10 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) > >>> } > >>> } > >>> > >>> + intel_dig_port->dp.output_reg = INVALID_MMIO_REG; > >>> intel_dig_port->max_lanes = max_lanes; > >>> > >>> - intel_encoder->type = INTEL_OUTPUT_UNKNOWN; > >>> + intel_encoder->type = INTEL_OUTPUT_DDI; > >>> intel_encoder->power_domain = intel_port_to_power_domain(port); > >>> intel_encoder->port = port; > >>> intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); > >>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > >>> index bd62c0a65bcd..a7e02ae33583 100644 > >>> --- a/drivers/gpu/drm/i915/intel_display.c > >>> +++ b/drivers/gpu/drm/i915/intel_display.c > >>> @@ -10591,7 +10591,7 @@ static const char * const output_type_str[] = { > >>> OUTPUT_TYPE(DP), > >>> OUTPUT_TYPE(EDP), > >>> OUTPUT_TYPE(DSI), > >>> - OUTPUT_TYPE(UNKNOWN), > >>> + OUTPUT_TYPE(DDI), > >>> OUTPUT_TYPE(DP_MST), > >>> }; > >>> > >>> @@ -10762,7 +10762,7 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state) > >>> > >>> switch (encoder->type) { > >>> unsigned int port_mask; > >>> - case INTEL_OUTPUT_UNKNOWN: > >>> + case INTEL_OUTPUT_DDI: > >>> if (WARN_ON(!HAS_DDI(to_i915(dev)))) > >>> break; > >>> case INTEL_OUTPUT_DP: > >>> @@ -10895,7 +10895,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, > >>> * Determine output_types before calling the .compute_config() > >>> * hooks so that the hooks can use this information safely. > >>> */ > >>> - pipe_config->output_types |= 1 << encoder->type; > >>> + if (encoder->compute_output_type) > >>> + pipe_config->output_types |= > >>> + BIT(encoder->compute_output_type(encoder, pipe_config, > >>> + connector_state)); > >>> + else > >>> + pipe_config->output_types |= BIT(encoder->type); > >>> } > >>> > >>> encoder_retry: > >>> @@ -11572,10 +11577,8 @@ verify_crtc_state(struct drm_crtc *crtc, > >>> "Encoder connected to wrong pipe %c\n", > >>> pipe_name(pipe)); > >>> > >>> - if (active) { > >>> - pipe_config->output_types |= 1 << encoder->type; > >>> + if (active) > >>> encoder->get_config(encoder, pipe_config); > >>> - } > >>> } > >>> > >>> intel_crtc_compute_pixel_rate(pipe_config); > >>> @@ -14963,7 +14966,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) > >>> crtc_state = to_intel_crtc_state(crtc->base.state); > >>> > >>> encoder->base.crtc = &crtc->base; > >>> - crtc_state->output_types |= 1 << encoder->type; > >>> encoder->get_config(encoder, crtc_state); > >>> } else { > >>> encoder->base.crtc = NULL; > >>> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > >>> index aa75f55eeb61..2b482d12000e 100644 > >>> --- a/drivers/gpu/drm/i915/intel_dp.c > >>> +++ b/drivers/gpu/drm/i915/intel_dp.c > >>> @@ -758,11 +758,16 @@ void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) > >>> struct intel_dp *intel_dp; > >>> > >>> if (encoder->type != INTEL_OUTPUT_DP && > >>> - encoder->type != INTEL_OUTPUT_EDP) > >>> + encoder->type != INTEL_OUTPUT_EDP && > >>> + encoder->type != INTEL_OUTPUT_DDI) > >>> continue; > >>> > >>> intel_dp = enc_to_intel_dp(&encoder->base); > >>> > >>> + /* Skip pure DVI/HDMI DDI encoders */ > >>> + if (!i915_mmio_reg_valid(intel_dp->output_reg)) > >>> + continue; > >>> + > >>> WARN_ON(intel_dp->active_pipe != INVALID_PIPE); > >>> > >>> if (encoder->type != INTEL_OUTPUT_EDP) > >>> @@ -2603,6 +2608,11 @@ static void intel_dp_get_config(struct intel_encoder *encoder, > >>> enum port port = dp_to_dig_port(intel_dp)->port; > >>> struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); > >>> > >>> + if (encoder->type == INTEL_OUTPUT_EDP) > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); > >>> + else > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); > >>> + > >>> tmp = I915_READ(intel_dp->output_reg); > >>> > >>> pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A; > >>> @@ -4699,8 +4709,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) > >>> { > >>> struct drm_connector *connector = &intel_connector->base; > >>> struct intel_dp *intel_dp = intel_attached_dp(connector); > >>> - struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); > >>> - struct intel_encoder *intel_encoder = &intel_dig_port->base; > >>> struct drm_device *dev = connector->dev; > >>> enum drm_connector_status status; > >>> u8 sink_irq_vector = 0; > >>> @@ -4733,9 +4741,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) > >>> goto out; > >>> } > >>> > >>> - if (intel_encoder->type != INTEL_OUTPUT_EDP) > >>> - intel_encoder->type = INTEL_OUTPUT_DP; > >>> - > >>> if (intel_dp->reset_link_params) { > >>> /* Initial max link lane count */ > >>> intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); > >>> @@ -4852,9 +4857,6 @@ intel_dp_force(struct drm_connector *connector) > >>> intel_dp_set_edid(intel_dp); > >>> > >>> intel_display_power_put(dev_priv, intel_dp->aux_power_domain); > >>> - > >>> - if (intel_encoder->type != INTEL_OUTPUT_EDP) > >>> - intel_encoder->type = INTEL_OUTPUT_DP; > >>> } > >>> > >>> static int intel_dp_get_modes(struct drm_connector *connector) > >>> @@ -5073,10 +5075,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) > >>> struct drm_i915_private *dev_priv = to_i915(dev); > >>> enum irqreturn ret = IRQ_NONE; > >>> > >>> - if (intel_dig_port->base.type != INTEL_OUTPUT_EDP && > >>> - intel_dig_port->base.type != INTEL_OUTPUT_HDMI) > >>> - intel_dig_port->base.type = INTEL_OUTPUT_DP; > >>> - > >>> if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { > >>> /* > >>> * vdd off can generate a long pulse on eDP which > >>> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c > >>> index 772521440a9f..9be6f32bb100 100644 > >>> --- a/drivers/gpu/drm/i915/intel_dp_mst.c > >>> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c > >>> @@ -270,6 +270,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, > >>> enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; > >>> u32 temp, flags = 0; > >>> > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); > >>> + > >>> pipe_config->has_audio = > >>> intel_ddi_is_audio_enabled(dev_priv, crtc); > >>> > >>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > >>> index a05ab3a1ab27..650129980ce2 100644 > >>> --- a/drivers/gpu/drm/i915/intel_drv.h > >>> +++ b/drivers/gpu/drm/i915/intel_drv.h > >>> @@ -173,7 +173,7 @@ enum intel_output_type { > >>> INTEL_OUTPUT_DP = 7, > >>> INTEL_OUTPUT_EDP = 8, > >>> INTEL_OUTPUT_DSI = 9, > >>> - INTEL_OUTPUT_UNKNOWN = 10, > >>> + INTEL_OUTPUT_DDI = 10, > >>> INTEL_OUTPUT_DP_MST = 11, > >>> }; > >>> > >>> @@ -216,6 +216,9 @@ struct intel_encoder { > >>> enum port port; > >>> unsigned int cloneable; > >>> void (*hot_plug)(struct intel_encoder *); > >>> + enum intel_output_type (*compute_output_type)(struct intel_encoder *, > >>> + struct intel_crtc_state *, > >>> + struct drm_connector_state *); > >>> bool (*compute_config)(struct intel_encoder *, > >>> struct intel_crtc_state *, > >>> struct drm_connector_state *); > >>> @@ -1149,7 +1152,7 @@ enc_to_dig_port(struct drm_encoder *encoder) > >>> struct intel_encoder *intel_encoder = to_intel_encoder(encoder); > >>> > >>> switch (intel_encoder->type) { > >>> - case INTEL_OUTPUT_UNKNOWN: > >>> + case INTEL_OUTPUT_DDI: > >>> WARN_ON(!HAS_DDI(to_i915(encoder->dev))); > >>> case INTEL_OUTPUT_DP: > >>> case INTEL_OUTPUT_EDP: > >>> diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c > >>> index 66bbedc5fa01..2ae3eea19317 100644 > >>> --- a/drivers/gpu/drm/i915/intel_dsi.c > >>> +++ b/drivers/gpu/drm/i915/intel_dsi.c > >>> @@ -1243,6 +1243,8 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, > >>> u32 pclk; > >>> DRM_DEBUG_KMS("\n"); > >>> > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI); > >>> + > >>> if (IS_GEN9_LP(dev_priv)) > >>> bxt_dsi_get_pipe_config(encoder, pipe_config); > >>> > >>> diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c > >>> index 53c9b763f4ce..754baa00bea9 100644 > >>> --- a/drivers/gpu/drm/i915/intel_dvo.c > >>> +++ b/drivers/gpu/drm/i915/intel_dvo.c > >>> @@ -159,6 +159,8 @@ static void intel_dvo_get_config(struct intel_encoder *encoder, > >>> struct intel_dvo *intel_dvo = enc_to_dvo(encoder); > >>> u32 tmp, flags = 0; > >>> > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_DVO); > >>> + > >>> tmp = I915_READ(intel_dvo->dev.dvo_reg); > >>> if (tmp & DVO_HSYNC_ACTIVE_HIGH) > >>> flags |= DRM_MODE_FLAG_PHSYNC; > >>> diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > >>> index 5132dc814788..1ff448a67b99 100644 > >>> --- a/drivers/gpu/drm/i915/intel_hdmi.c > >>> +++ b/drivers/gpu/drm/i915/intel_hdmi.c > >>> @@ -957,6 +957,8 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, > >>> u32 tmp, flags = 0; > >>> int dotclock; > >>> > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); > >>> + > >>> tmp = I915_READ(intel_hdmi->hdmi_reg); > >>> > >>> if (tmp & SDVO_HSYNC_ACTIVE_HIGH) > >>> @@ -1610,12 +1612,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) > >>> > >>> intel_hdmi_unset_edid(connector); > >>> > >>> - if (intel_hdmi_set_edid(connector)) { > >>> - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > >>> - > >>> - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; > >>> + if (intel_hdmi_set_edid(connector)) > >>> status = connector_status_connected; > >>> - } else > >>> + else > >>> status = connector_status_disconnected; > >>> > >>> intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); > >>> @@ -1626,8 +1625,6 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) > >>> static void > >>> intel_hdmi_force(struct drm_connector *connector) > >>> { > >>> - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > >>> - > >>> DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", > >>> connector->base.id, connector->name); > >>> > >>> @@ -1637,7 +1634,6 @@ intel_hdmi_force(struct drm_connector *connector) > >>> return; > >>> > >>> intel_hdmi_set_edid(connector); > >>> - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; > >>> } > >>> > >>> static int intel_hdmi_get_modes(struct drm_connector *connector) > >>> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c > >>> index 38572d65e46e..ef80499113ee 100644 > >>> --- a/drivers/gpu/drm/i915/intel_lvds.c > >>> +++ b/drivers/gpu/drm/i915/intel_lvds.c > >>> @@ -125,6 +125,8 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, > >>> struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); > >>> u32 tmp, flags = 0; > >>> > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_LVDS); > >>> + > >>> tmp = I915_READ(lvds_encoder->reg); > >>> if (tmp & LVDS_HSYNC_POLARITY) > >>> flags |= DRM_MODE_FLAG_NHSYNC; > >>> diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c > >>> index 1d946240e55f..39714be3eb6b 100644 > >>> --- a/drivers/gpu/drm/i915/intel_opregion.c > >>> +++ b/drivers/gpu/drm/i915/intel_opregion.c > >>> @@ -383,7 +383,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, > >>> case INTEL_OUTPUT_ANALOG: > >>> type = DISPLAY_TYPE_CRT; > >>> break; > >>> - case INTEL_OUTPUT_UNKNOWN: > >>> + case INTEL_OUTPUT_DDI: > >>> case INTEL_OUTPUT_DP: > >>> case INTEL_OUTPUT_HDMI: > >>> case INTEL_OUTPUT_DP_MST: > >>> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c > >>> index 7437944b388f..42ec2d1f7a61 100644 > >>> --- a/drivers/gpu/drm/i915/intel_sdvo.c > >>> +++ b/drivers/gpu/drm/i915/intel_sdvo.c > >>> @@ -1429,6 +1429,8 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, > >>> u8 val; > >>> bool ret; > >>> > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_SDVO); > >>> + > >>> sdvox = I915_READ(intel_sdvo->sdvo_reg); > >>> > >>> ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); > >>> diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c > >>> index a79a7591b2cf..b18609cebe03 100644 > >>> --- a/drivers/gpu/drm/i915/intel_tv.c > >>> +++ b/drivers/gpu/drm/i915/intel_tv.c > >>> @@ -868,6 +868,8 @@ static void > >>> intel_tv_get_config(struct intel_encoder *encoder, > >>> struct intel_crtc_state *pipe_config) > >>> { > >>> + pipe_config->output_types |= BIT(INTEL_OUTPUT_TVOUT); > >>> + > >>> pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; > >>> } > >>> >
Op 27-10-17 om 16:03 schreef Ville Syrjälä: > On Fri, Oct 27, 2017 at 03:53:34PM +0200, Maarten Lankhorst wrote: >> Op 27-10-17 om 14:44 schreef Ville Syrjälä: >>> On Fri, Oct 27, 2017 at 02:05:38PM +0200, Maarten Lankhorst wrote: >>>> Op 19-10-17 om 15:37 schreef Ville Syrjala: >>>>> From: Ville Syrjälä <ville.syrjala@linux.intel.com> >>>>> >>>>> Currently the DDI encoder->type will change at runtime depending on >>>>> what kind of hotplugs we've processed. That's quite bad since we can't >>>>> really trust that that current value of encoder->type actually matches >>>>> the type of signal we're trying to drive through it. >>>>> >>>>> Let's eliminate that problem by declaring that non-eDP DDI port will >>>>> always have the encoder type as INTEL_OUTPUT_DDI. This means the code >>>>> can no longer try to distinguish DP vs. HDMI based on encoder->type. >>>>> We'll leave eDP as INTEL_OUTPUT_EDP, since it'll never change and >>>>> there's a bunch of code that relies on that value to identify eDP >>>>> encoders. >>>>> >>>>> We'll introduce a new encoder .compute_output_type() hook. This allows >>>>> us to compute the full output_types before any encoder .compute_config() >>>>> hooks get called, thus those hooks can rely on output_types being >>>>> correct, which is useful for cloning on oldr platforms. For now we'll >>>>> just look at the connector type and pick the correct mode based on that. >>>>> In the future the new hook could be used to implement dynamic switching >>>>> between LS and PCON modes for LSPCON. >>>>> >>>>> TODO: maybe make .get_config() populate output_types rather than doing >>>>> the default encoder->type thing in caller and then undoing it for >>>>> DDI in .get_config(). >>>>> >>>>> v2: Fix BXT/GLK PPS explosion with DSI/MST encoders >>>>> v3: Avoid the PPS warn on pure HDMI/DVI DDI encoders by checking dp.output_reg >>>>> v4: Rebase >>>>> v5: Populate output_types in .get_config() rather than in the caller >>>> Could we get rid of compute_output_type in this patch? Perhaps do it as preliminary >>>> patch towards removing the use? >>> We don't want to remove it. >> Ok, but could that still be a separate preparation patch? That would make it easier to review. :) > Not sure which part you mean here. Moving the 'output_types |= whatever' > into .get_config()? Hmm. Yeah that should be easy to split out. I guess > it won't even make the DDI case any more broken that it already is since > even currently encoder->type might change between the modeset compute > phase and .get_config(). And it's going to be followed closely by the > actual fix anyway. > Yes, that part. It should work even without the UNKNOWN->DDI change afaics.
On Fri, Oct 27, 2017 at 02:05:38PM +0200, Maarten Lankhorst wrote: > Op 19-10-17 om 15:37 schreef Ville Syrjala: > > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > > > Currently the DDI encoder->type will change at runtime depending on > > what kind of hotplugs we've processed. That's quite bad since we can't > > really trust that that current value of encoder->type actually matches > > the type of signal we're trying to drive through it. > > > > Let's eliminate that problem by declaring that non-eDP DDI port will > > always have the encoder type as INTEL_OUTPUT_DDI. This means the code > > can no longer try to distinguish DP vs. HDMI based on encoder->type. > > We'll leave eDP as INTEL_OUTPUT_EDP, since it'll never change and > > there's a bunch of code that relies on that value to identify eDP > > encoders. > > > > We'll introduce a new encoder .compute_output_type() hook. This allows > > us to compute the full output_types before any encoder .compute_config() > > hooks get called, thus those hooks can rely on output_types being > > correct, which is useful for cloning on oldr platforms. For now we'll > > just look at the connector type and pick the correct mode based on that. > > In the future the new hook could be used to implement dynamic switching > > between LS and PCON modes for LSPCON. > > > > TODO: maybe make .get_config() populate output_types rather than doing > > the default encoder->type thing in caller and then undoing it for > > DDI in .get_config(). > > > > v2: Fix BXT/GLK PPS explosion with DSI/MST encoders > > v3: Avoid the PPS warn on pure HDMI/DVI DDI encoders by checking dp.output_reg > > v4: Rebase > > v5: Populate output_types in .get_config() rather than in the caller > > Could we get rid of compute_output_type in this patch? Perhaps do it as preliminary > patch towards removing the use? > > Rest of the series except patch 8 looks good. For patch 1-4, 6, 7, 9 (if the delta > between ddi_get_config and old mst get_config is harmless or beneficial) and 10: > > Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Thanks. First four patches pushed to dinq. The rest reposted as a new series, with this patch split up. > > Thanks for the work towards cleaning this mess up. > > ~Maarten > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > > --- > > drivers/gpu/drm/i915/i915_debugfs.c | 2 +- > > drivers/gpu/drm/i915/intel_crt.c | 2 ++ > > drivers/gpu/drm/i915/intel_ddi.c | 43 ++++++++++++++++++++++++++++------- > > drivers/gpu/drm/i915/intel_display.c | 16 +++++++------ > > drivers/gpu/drm/i915/intel_dp.c | 24 +++++++++---------- > > drivers/gpu/drm/i915/intel_dp_mst.c | 2 ++ > > drivers/gpu/drm/i915/intel_drv.h | 7 ++++-- > > drivers/gpu/drm/i915/intel_dsi.c | 2 ++ > > drivers/gpu/drm/i915/intel_dvo.c | 2 ++ > > drivers/gpu/drm/i915/intel_hdmi.c | 12 ++++------ > > drivers/gpu/drm/i915/intel_lvds.c | 2 ++ > > drivers/gpu/drm/i915/intel_opregion.c | 2 +- > > drivers/gpu/drm/i915/intel_sdvo.c | 2 ++ > > drivers/gpu/drm/i915/intel_tv.c | 2 ++ > > 14 files changed, 80 insertions(+), 40 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c > > index c65e381b85f3..e5333bfdf32d 100644 > > --- a/drivers/gpu/drm/i915/i915_debugfs.c > > +++ b/drivers/gpu/drm/i915/i915_debugfs.c > > @@ -3049,7 +3049,7 @@ static void intel_connector_info(struct seq_file *m, > > break; > > case DRM_MODE_CONNECTOR_HDMIA: > > if (intel_encoder->type == INTEL_OUTPUT_HDMI || > > - intel_encoder->type == INTEL_OUTPUT_UNKNOWN) > > + intel_encoder->type == INTEL_OUTPUT_DDI) > > intel_hdmi_info(m, intel_connector); > > break; > > default: > > diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c > > index 668e8c3e791d..a61e61efe9aa 100644 > > --- a/drivers/gpu/drm/i915/intel_crt.c > > +++ b/drivers/gpu/drm/i915/intel_crt.c > > @@ -119,6 +119,8 @@ static unsigned int intel_crt_get_flags(struct intel_encoder *encoder) > > static void intel_crt_get_config(struct intel_encoder *encoder, > > struct intel_crtc_state *pipe_config) > > { > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); > > + > > pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder); > > > > pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c > > index c8790bb74839..630609575db4 100644 > > --- a/drivers/gpu/drm/i915/intel_ddi.c > > +++ b/drivers/gpu/drm/i915/intel_ddi.c > > @@ -497,10 +497,8 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *encoder) > > switch (encoder->type) { > > case INTEL_OUTPUT_DP_MST: > > return enc_to_mst(&encoder->base)->primary->port; > > - case INTEL_OUTPUT_DP: > > case INTEL_OUTPUT_EDP: > > - case INTEL_OUTPUT_HDMI: > > - case INTEL_OUTPUT_UNKNOWN: > > + case INTEL_OUTPUT_DDI: > > return enc_to_dig_port(&encoder->base)->port; > > case INTEL_OUTPUT_ANALOG: > > return PORT_E; > > @@ -1532,6 +1530,7 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, > > struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > > enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; > > uint32_t temp; > > + > > temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); > > if (state == true) > > temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC; > > @@ -2586,12 +2585,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder, > > pipe_config->hdmi_high_tmds_clock_ratio = true; > > /* fall through */ > > case TRANS_DDI_MODE_SELECT_DVI: > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); > > pipe_config->lane_count = 4; > > break; > > case TRANS_DDI_MODE_SELECT_FDI: > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); > > break; > > case TRANS_DDI_MODE_SELECT_DP_SST: > > + if (encoder->type == INTEL_OUTPUT_EDP) > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); > > + else > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); > > + pipe_config->lane_count = > > + ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; > > + intel_dp_get_m_n(intel_crtc, pipe_config); > > + break; > > case TRANS_DDI_MODE_SELECT_DP_MST: > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); > > pipe_config->lane_count = > > ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; > > intel_dp_get_m_n(intel_crtc, pipe_config); > > @@ -2630,21 +2640,36 @@ void intel_ddi_get_config(struct intel_encoder *encoder, > > bxt_ddi_phy_get_lane_lat_optim_mask(encoder); > > } > > > > +static enum intel_output_type > > +intel_ddi_compute_output_type(struct intel_encoder *encoder, > > + struct intel_crtc_state *crtc_state, > > + struct drm_connector_state *conn_state) > > +{ > > + switch (conn_state->connector->connector_type) { > > + case DRM_MODE_CONNECTOR_HDMIA: > > + return INTEL_OUTPUT_HDMI; > > + case DRM_MODE_CONNECTOR_eDP: > > + return INTEL_OUTPUT_EDP; > > + case DRM_MODE_CONNECTOR_DisplayPort: > > + return INTEL_OUTPUT_DP; > > + default: > > + MISSING_CASE(conn_state->connector->connector_type); > > + return INTEL_OUTPUT_UNUSED; > > + } > > +} > > + > > static bool intel_ddi_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); > > - int type = encoder->type; > > int port = intel_ddi_get_encoder_port(encoder); > > int ret; > > > > - WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); > > - > > if (port == PORT_A) > > pipe_config->cpu_transcoder = TRANSCODER_EDP; > > > > - if (type == INTEL_OUTPUT_HDMI) > > + if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) > > ret = intel_hdmi_compute_config(encoder, pipe_config, conn_state); > > else > > ret = intel_dp_compute_config(encoder, pipe_config, conn_state); > > @@ -2764,6 +2789,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) > > drm_encoder_init(&dev_priv->drm, encoder, &intel_ddi_funcs, > > DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port)); > > > > + intel_encoder->compute_output_type = intel_ddi_compute_output_type; > > intel_encoder->compute_config = intel_ddi_compute_config; > > intel_encoder->enable = intel_enable_ddi; > > if (IS_GEN9_LP(dev_priv)) > > @@ -2821,9 +2847,10 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) > > } > > } > > > > + intel_dig_port->dp.output_reg = INVALID_MMIO_REG; > > intel_dig_port->max_lanes = max_lanes; > > > > - intel_encoder->type = INTEL_OUTPUT_UNKNOWN; > > + intel_encoder->type = INTEL_OUTPUT_DDI; > > intel_encoder->power_domain = intel_port_to_power_domain(port); > > intel_encoder->port = port; > > intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > > index bd62c0a65bcd..a7e02ae33583 100644 > > --- a/drivers/gpu/drm/i915/intel_display.c > > +++ b/drivers/gpu/drm/i915/intel_display.c > > @@ -10591,7 +10591,7 @@ static const char * const output_type_str[] = { > > OUTPUT_TYPE(DP), > > OUTPUT_TYPE(EDP), > > OUTPUT_TYPE(DSI), > > - OUTPUT_TYPE(UNKNOWN), > > + OUTPUT_TYPE(DDI), > > OUTPUT_TYPE(DP_MST), > > }; > > > > @@ -10762,7 +10762,7 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state) > > > > switch (encoder->type) { > > unsigned int port_mask; > > - case INTEL_OUTPUT_UNKNOWN: > > + case INTEL_OUTPUT_DDI: > > if (WARN_ON(!HAS_DDI(to_i915(dev)))) > > break; > > case INTEL_OUTPUT_DP: > > @@ -10895,7 +10895,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, > > * Determine output_types before calling the .compute_config() > > * hooks so that the hooks can use this information safely. > > */ > > - pipe_config->output_types |= 1 << encoder->type; > > + if (encoder->compute_output_type) > > + pipe_config->output_types |= > > + BIT(encoder->compute_output_type(encoder, pipe_config, > > + connector_state)); > > + else > > + pipe_config->output_types |= BIT(encoder->type); > > } > > > > encoder_retry: > > @@ -11572,10 +11577,8 @@ verify_crtc_state(struct drm_crtc *crtc, > > "Encoder connected to wrong pipe %c\n", > > pipe_name(pipe)); > > > > - if (active) { > > - pipe_config->output_types |= 1 << encoder->type; > > + if (active) > > encoder->get_config(encoder, pipe_config); > > - } > > } > > > > intel_crtc_compute_pixel_rate(pipe_config); > > @@ -14963,7 +14966,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) > > crtc_state = to_intel_crtc_state(crtc->base.state); > > > > encoder->base.crtc = &crtc->base; > > - crtc_state->output_types |= 1 << encoder->type; > > encoder->get_config(encoder, crtc_state); > > } else { > > encoder->base.crtc = NULL; > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > > index aa75f55eeb61..2b482d12000e 100644 > > --- a/drivers/gpu/drm/i915/intel_dp.c > > +++ b/drivers/gpu/drm/i915/intel_dp.c > > @@ -758,11 +758,16 @@ void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) > > struct intel_dp *intel_dp; > > > > if (encoder->type != INTEL_OUTPUT_DP && > > - encoder->type != INTEL_OUTPUT_EDP) > > + encoder->type != INTEL_OUTPUT_EDP && > > + encoder->type != INTEL_OUTPUT_DDI) > > continue; > > > > intel_dp = enc_to_intel_dp(&encoder->base); > > > > + /* Skip pure DVI/HDMI DDI encoders */ > > + if (!i915_mmio_reg_valid(intel_dp->output_reg)) > > + continue; > > + > > WARN_ON(intel_dp->active_pipe != INVALID_PIPE); > > > > if (encoder->type != INTEL_OUTPUT_EDP) > > @@ -2603,6 +2608,11 @@ static void intel_dp_get_config(struct intel_encoder *encoder, > > enum port port = dp_to_dig_port(intel_dp)->port; > > struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); > > > > + if (encoder->type == INTEL_OUTPUT_EDP) > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); > > + else > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); > > + > > tmp = I915_READ(intel_dp->output_reg); > > > > pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A; > > @@ -4699,8 +4709,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) > > { > > struct drm_connector *connector = &intel_connector->base; > > struct intel_dp *intel_dp = intel_attached_dp(connector); > > - struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); > > - struct intel_encoder *intel_encoder = &intel_dig_port->base; > > struct drm_device *dev = connector->dev; > > enum drm_connector_status status; > > u8 sink_irq_vector = 0; > > @@ -4733,9 +4741,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) > > goto out; > > } > > > > - if (intel_encoder->type != INTEL_OUTPUT_EDP) > > - intel_encoder->type = INTEL_OUTPUT_DP; > > - > > if (intel_dp->reset_link_params) { > > /* Initial max link lane count */ > > intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); > > @@ -4852,9 +4857,6 @@ intel_dp_force(struct drm_connector *connector) > > intel_dp_set_edid(intel_dp); > > > > intel_display_power_put(dev_priv, intel_dp->aux_power_domain); > > - > > - if (intel_encoder->type != INTEL_OUTPUT_EDP) > > - intel_encoder->type = INTEL_OUTPUT_DP; > > } > > > > static int intel_dp_get_modes(struct drm_connector *connector) > > @@ -5073,10 +5075,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) > > struct drm_i915_private *dev_priv = to_i915(dev); > > enum irqreturn ret = IRQ_NONE; > > > > - if (intel_dig_port->base.type != INTEL_OUTPUT_EDP && > > - intel_dig_port->base.type != INTEL_OUTPUT_HDMI) > > - intel_dig_port->base.type = INTEL_OUTPUT_DP; > > - > > if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { > > /* > > * vdd off can generate a long pulse on eDP which > > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c > > index 772521440a9f..9be6f32bb100 100644 > > --- a/drivers/gpu/drm/i915/intel_dp_mst.c > > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c > > @@ -270,6 +270,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, > > enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; > > u32 temp, flags = 0; > > > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); > > + > > pipe_config->has_audio = > > intel_ddi_is_audio_enabled(dev_priv, crtc); > > > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > > index a05ab3a1ab27..650129980ce2 100644 > > --- a/drivers/gpu/drm/i915/intel_drv.h > > +++ b/drivers/gpu/drm/i915/intel_drv.h > > @@ -173,7 +173,7 @@ enum intel_output_type { > > INTEL_OUTPUT_DP = 7, > > INTEL_OUTPUT_EDP = 8, > > INTEL_OUTPUT_DSI = 9, > > - INTEL_OUTPUT_UNKNOWN = 10, > > + INTEL_OUTPUT_DDI = 10, > > INTEL_OUTPUT_DP_MST = 11, > > }; > > > > @@ -216,6 +216,9 @@ struct intel_encoder { > > enum port port; > > unsigned int cloneable; > > void (*hot_plug)(struct intel_encoder *); > > + enum intel_output_type (*compute_output_type)(struct intel_encoder *, > > + struct intel_crtc_state *, > > + struct drm_connector_state *); > > bool (*compute_config)(struct intel_encoder *, > > struct intel_crtc_state *, > > struct drm_connector_state *); > > @@ -1149,7 +1152,7 @@ enc_to_dig_port(struct drm_encoder *encoder) > > struct intel_encoder *intel_encoder = to_intel_encoder(encoder); > > > > switch (intel_encoder->type) { > > - case INTEL_OUTPUT_UNKNOWN: > > + case INTEL_OUTPUT_DDI: > > WARN_ON(!HAS_DDI(to_i915(encoder->dev))); > > case INTEL_OUTPUT_DP: > > case INTEL_OUTPUT_EDP: > > diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c > > index 66bbedc5fa01..2ae3eea19317 100644 > > --- a/drivers/gpu/drm/i915/intel_dsi.c > > +++ b/drivers/gpu/drm/i915/intel_dsi.c > > @@ -1243,6 +1243,8 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, > > u32 pclk; > > DRM_DEBUG_KMS("\n"); > > > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI); > > + > > if (IS_GEN9_LP(dev_priv)) > > bxt_dsi_get_pipe_config(encoder, pipe_config); > > > > diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c > > index 53c9b763f4ce..754baa00bea9 100644 > > --- a/drivers/gpu/drm/i915/intel_dvo.c > > +++ b/drivers/gpu/drm/i915/intel_dvo.c > > @@ -159,6 +159,8 @@ static void intel_dvo_get_config(struct intel_encoder *encoder, > > struct intel_dvo *intel_dvo = enc_to_dvo(encoder); > > u32 tmp, flags = 0; > > > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_DVO); > > + > > tmp = I915_READ(intel_dvo->dev.dvo_reg); > > if (tmp & DVO_HSYNC_ACTIVE_HIGH) > > flags |= DRM_MODE_FLAG_PHSYNC; > > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > > index 5132dc814788..1ff448a67b99 100644 > > --- a/drivers/gpu/drm/i915/intel_hdmi.c > > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > > @@ -957,6 +957,8 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, > > u32 tmp, flags = 0; > > int dotclock; > > > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); > > + > > tmp = I915_READ(intel_hdmi->hdmi_reg); > > > > if (tmp & SDVO_HSYNC_ACTIVE_HIGH) > > @@ -1610,12 +1612,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) > > > > intel_hdmi_unset_edid(connector); > > > > - if (intel_hdmi_set_edid(connector)) { > > - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > > - > > - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; > > + if (intel_hdmi_set_edid(connector)) > > status = connector_status_connected; > > - } else > > + else > > status = connector_status_disconnected; > > > > intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); > > @@ -1626,8 +1625,6 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) > > static void > > intel_hdmi_force(struct drm_connector *connector) > > { > > - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > > - > > DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", > > connector->base.id, connector->name); > > > > @@ -1637,7 +1634,6 @@ intel_hdmi_force(struct drm_connector *connector) > > return; > > > > intel_hdmi_set_edid(connector); > > - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; > > } > > > > static int intel_hdmi_get_modes(struct drm_connector *connector) > > diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c > > index 38572d65e46e..ef80499113ee 100644 > > --- a/drivers/gpu/drm/i915/intel_lvds.c > > +++ b/drivers/gpu/drm/i915/intel_lvds.c > > @@ -125,6 +125,8 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, > > struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); > > u32 tmp, flags = 0; > > > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_LVDS); > > + > > tmp = I915_READ(lvds_encoder->reg); > > if (tmp & LVDS_HSYNC_POLARITY) > > flags |= DRM_MODE_FLAG_NHSYNC; > > diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c > > index 1d946240e55f..39714be3eb6b 100644 > > --- a/drivers/gpu/drm/i915/intel_opregion.c > > +++ b/drivers/gpu/drm/i915/intel_opregion.c > > @@ -383,7 +383,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, > > case INTEL_OUTPUT_ANALOG: > > type = DISPLAY_TYPE_CRT; > > break; > > - case INTEL_OUTPUT_UNKNOWN: > > + case INTEL_OUTPUT_DDI: > > case INTEL_OUTPUT_DP: > > case INTEL_OUTPUT_HDMI: > > case INTEL_OUTPUT_DP_MST: > > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c > > index 7437944b388f..42ec2d1f7a61 100644 > > --- a/drivers/gpu/drm/i915/intel_sdvo.c > > +++ b/drivers/gpu/drm/i915/intel_sdvo.c > > @@ -1429,6 +1429,8 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, > > u8 val; > > bool ret; > > > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_SDVO); > > + > > sdvox = I915_READ(intel_sdvo->sdvo_reg); > > > > ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); > > diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c > > index a79a7591b2cf..b18609cebe03 100644 > > --- a/drivers/gpu/drm/i915/intel_tv.c > > +++ b/drivers/gpu/drm/i915/intel_tv.c > > @@ -868,6 +868,8 @@ static void > > intel_tv_get_config(struct intel_encoder *encoder, > > struct intel_crtc_state *pipe_config) > > { > > + pipe_config->output_types |= BIT(INTEL_OUTPUT_TVOUT); > > + > > pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; > > } > > >
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index c65e381b85f3..e5333bfdf32d 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -3049,7 +3049,7 @@ static void intel_connector_info(struct seq_file *m, break; case DRM_MODE_CONNECTOR_HDMIA: if (intel_encoder->type == INTEL_OUTPUT_HDMI || - intel_encoder->type == INTEL_OUTPUT_UNKNOWN) + intel_encoder->type == INTEL_OUTPUT_DDI) intel_hdmi_info(m, intel_connector); break; default: diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 668e8c3e791d..a61e61efe9aa 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -119,6 +119,8 @@ static unsigned int intel_crt_get_flags(struct intel_encoder *encoder) static void intel_crt_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { + pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); + pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder); pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index c8790bb74839..630609575db4 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -497,10 +497,8 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *encoder) switch (encoder->type) { case INTEL_OUTPUT_DP_MST: return enc_to_mst(&encoder->base)->primary->port; - case INTEL_OUTPUT_DP: case INTEL_OUTPUT_EDP: - case INTEL_OUTPUT_HDMI: - case INTEL_OUTPUT_UNKNOWN: + case INTEL_OUTPUT_DDI: return enc_to_dig_port(&encoder->base)->port; case INTEL_OUTPUT_ANALOG: return PORT_E; @@ -1532,6 +1530,7 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state, struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; uint32_t temp; + temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); if (state == true) temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC; @@ -2586,12 +2585,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder, pipe_config->hdmi_high_tmds_clock_ratio = true; /* fall through */ case TRANS_DDI_MODE_SELECT_DVI: + pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); pipe_config->lane_count = 4; break; case TRANS_DDI_MODE_SELECT_FDI: + pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG); break; case TRANS_DDI_MODE_SELECT_DP_SST: + if (encoder->type == INTEL_OUTPUT_EDP) + pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); + else + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); + pipe_config->lane_count = + ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; + intel_dp_get_m_n(intel_crtc, pipe_config); + break; case TRANS_DDI_MODE_SELECT_DP_MST: + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); pipe_config->lane_count = ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1; intel_dp_get_m_n(intel_crtc, pipe_config); @@ -2630,21 +2640,36 @@ void intel_ddi_get_config(struct intel_encoder *encoder, bxt_ddi_phy_get_lane_lat_optim_mask(encoder); } +static enum intel_output_type +intel_ddi_compute_output_type(struct intel_encoder *encoder, + struct intel_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + switch (conn_state->connector->connector_type) { + case DRM_MODE_CONNECTOR_HDMIA: + return INTEL_OUTPUT_HDMI; + case DRM_MODE_CONNECTOR_eDP: + return INTEL_OUTPUT_EDP; + case DRM_MODE_CONNECTOR_DisplayPort: + return INTEL_OUTPUT_DP; + default: + MISSING_CASE(conn_state->connector->connector_type); + return INTEL_OUTPUT_UNUSED; + } +} + static bool intel_ddi_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); - int type = encoder->type; int port = intel_ddi_get_encoder_port(encoder); int ret; - WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); - if (port == PORT_A) pipe_config->cpu_transcoder = TRANSCODER_EDP; - if (type == INTEL_OUTPUT_HDMI) + if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) ret = intel_hdmi_compute_config(encoder, pipe_config, conn_state); else ret = intel_dp_compute_config(encoder, pipe_config, conn_state); @@ -2764,6 +2789,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) drm_encoder_init(&dev_priv->drm, encoder, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port)); + intel_encoder->compute_output_type = intel_ddi_compute_output_type; intel_encoder->compute_config = intel_ddi_compute_config; intel_encoder->enable = intel_enable_ddi; if (IS_GEN9_LP(dev_priv)) @@ -2821,9 +2847,10 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) } } + intel_dig_port->dp.output_reg = INVALID_MMIO_REG; intel_dig_port->max_lanes = max_lanes; - intel_encoder->type = INTEL_OUTPUT_UNKNOWN; + intel_encoder->type = INTEL_OUTPUT_DDI; intel_encoder->power_domain = intel_port_to_power_domain(port); intel_encoder->port = port; intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index bd62c0a65bcd..a7e02ae33583 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -10591,7 +10591,7 @@ static const char * const output_type_str[] = { OUTPUT_TYPE(DP), OUTPUT_TYPE(EDP), OUTPUT_TYPE(DSI), - OUTPUT_TYPE(UNKNOWN), + OUTPUT_TYPE(DDI), OUTPUT_TYPE(DP_MST), }; @@ -10762,7 +10762,7 @@ static bool check_digital_port_conflicts(struct drm_atomic_state *state) switch (encoder->type) { unsigned int port_mask; - case INTEL_OUTPUT_UNKNOWN: + case INTEL_OUTPUT_DDI: if (WARN_ON(!HAS_DDI(to_i915(dev)))) break; case INTEL_OUTPUT_DP: @@ -10895,7 +10895,12 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, * Determine output_types before calling the .compute_config() * hooks so that the hooks can use this information safely. */ - pipe_config->output_types |= 1 << encoder->type; + if (encoder->compute_output_type) + pipe_config->output_types |= + BIT(encoder->compute_output_type(encoder, pipe_config, + connector_state)); + else + pipe_config->output_types |= BIT(encoder->type); } encoder_retry: @@ -11572,10 +11577,8 @@ verify_crtc_state(struct drm_crtc *crtc, "Encoder connected to wrong pipe %c\n", pipe_name(pipe)); - if (active) { - pipe_config->output_types |= 1 << encoder->type; + if (active) encoder->get_config(encoder, pipe_config); - } } intel_crtc_compute_pixel_rate(pipe_config); @@ -14963,7 +14966,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) crtc_state = to_intel_crtc_state(crtc->base.state); encoder->base.crtc = &crtc->base; - crtc_state->output_types |= 1 << encoder->type; encoder->get_config(encoder, crtc_state); } else { encoder->base.crtc = NULL; diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index aa75f55eeb61..2b482d12000e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -758,11 +758,16 @@ void intel_power_sequencer_reset(struct drm_i915_private *dev_priv) struct intel_dp *intel_dp; if (encoder->type != INTEL_OUTPUT_DP && - encoder->type != INTEL_OUTPUT_EDP) + encoder->type != INTEL_OUTPUT_EDP && + encoder->type != INTEL_OUTPUT_DDI) continue; intel_dp = enc_to_intel_dp(&encoder->base); + /* Skip pure DVI/HDMI DDI encoders */ + if (!i915_mmio_reg_valid(intel_dp->output_reg)) + continue; + WARN_ON(intel_dp->active_pipe != INVALID_PIPE); if (encoder->type != INTEL_OUTPUT_EDP) @@ -2603,6 +2608,11 @@ static void intel_dp_get_config(struct intel_encoder *encoder, enum port port = dp_to_dig_port(intel_dp)->port; struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); + if (encoder->type == INTEL_OUTPUT_EDP) + pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP); + else + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP); + tmp = I915_READ(intel_dp->output_reg); pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A; @@ -4699,8 +4709,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) { struct drm_connector *connector = &intel_connector->base; struct intel_dp *intel_dp = intel_attached_dp(connector); - struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct intel_encoder *intel_encoder = &intel_dig_port->base; struct drm_device *dev = connector->dev; enum drm_connector_status status; u8 sink_irq_vector = 0; @@ -4733,9 +4741,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector) goto out; } - if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DP; - if (intel_dp->reset_link_params) { /* Initial max link lane count */ intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); @@ -4852,9 +4857,6 @@ intel_dp_force(struct drm_connector *connector) intel_dp_set_edid(intel_dp); intel_display_power_put(dev_priv, intel_dp->aux_power_domain); - - if (intel_encoder->type != INTEL_OUTPUT_EDP) - intel_encoder->type = INTEL_OUTPUT_DP; } static int intel_dp_get_modes(struct drm_connector *connector) @@ -5073,10 +5075,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) struct drm_i915_private *dev_priv = to_i915(dev); enum irqreturn ret = IRQ_NONE; - if (intel_dig_port->base.type != INTEL_OUTPUT_EDP && - intel_dig_port->base.type != INTEL_OUTPUT_HDMI) - intel_dig_port->base.type = INTEL_OUTPUT_DP; - if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { /* * vdd off can generate a long pulse on eDP which diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 772521440a9f..9be6f32bb100 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -270,6 +270,8 @@ static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder, enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; u32 temp, flags = 0; + pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST); + pipe_config->has_audio = intel_ddi_is_audio_enabled(dev_priv, crtc); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a05ab3a1ab27..650129980ce2 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -173,7 +173,7 @@ enum intel_output_type { INTEL_OUTPUT_DP = 7, INTEL_OUTPUT_EDP = 8, INTEL_OUTPUT_DSI = 9, - INTEL_OUTPUT_UNKNOWN = 10, + INTEL_OUTPUT_DDI = 10, INTEL_OUTPUT_DP_MST = 11, }; @@ -216,6 +216,9 @@ struct intel_encoder { enum port port; unsigned int cloneable; void (*hot_plug)(struct intel_encoder *); + enum intel_output_type (*compute_output_type)(struct intel_encoder *, + struct intel_crtc_state *, + struct drm_connector_state *); bool (*compute_config)(struct intel_encoder *, struct intel_crtc_state *, struct drm_connector_state *); @@ -1149,7 +1152,7 @@ enc_to_dig_port(struct drm_encoder *encoder) struct intel_encoder *intel_encoder = to_intel_encoder(encoder); switch (intel_encoder->type) { - case INTEL_OUTPUT_UNKNOWN: + case INTEL_OUTPUT_DDI: WARN_ON(!HAS_DDI(to_i915(encoder->dev))); case INTEL_OUTPUT_DP: case INTEL_OUTPUT_EDP: diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 66bbedc5fa01..2ae3eea19317 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1243,6 +1243,8 @@ static void intel_dsi_get_config(struct intel_encoder *encoder, u32 pclk; DRM_DEBUG_KMS("\n"); + pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI); + if (IS_GEN9_LP(dev_priv)) bxt_dsi_get_pipe_config(encoder, pipe_config); diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 53c9b763f4ce..754baa00bea9 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -159,6 +159,8 @@ static void intel_dvo_get_config(struct intel_encoder *encoder, struct intel_dvo *intel_dvo = enc_to_dvo(encoder); u32 tmp, flags = 0; + pipe_config->output_types |= BIT(INTEL_OUTPUT_DVO); + tmp = I915_READ(intel_dvo->dev.dvo_reg); if (tmp & DVO_HSYNC_ACTIVE_HIGH) flags |= DRM_MODE_FLAG_PHSYNC; diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 5132dc814788..1ff448a67b99 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -957,6 +957,8 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, u32 tmp, flags = 0; int dotclock; + pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI); + tmp = I915_READ(intel_hdmi->hdmi_reg); if (tmp & SDVO_HSYNC_ACTIVE_HIGH) @@ -1610,12 +1612,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) intel_hdmi_unset_edid(connector); - if (intel_hdmi_set_edid(connector)) { - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; + if (intel_hdmi_set_edid(connector)) status = connector_status_connected; - } else + else status = connector_status_disconnected; intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); @@ -1626,8 +1625,6 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) static void intel_hdmi_force(struct drm_connector *connector) { - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); @@ -1637,7 +1634,6 @@ intel_hdmi_force(struct drm_connector *connector) return; intel_hdmi_set_edid(connector); - hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI; } static int intel_hdmi_get_modes(struct drm_connector *connector) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 38572d65e46e..ef80499113ee 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -125,6 +125,8 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); u32 tmp, flags = 0; + pipe_config->output_types |= BIT(INTEL_OUTPUT_LVDS); + tmp = I915_READ(lvds_encoder->reg); if (tmp & LVDS_HSYNC_POLARITY) flags |= DRM_MODE_FLAG_NHSYNC; diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 1d946240e55f..39714be3eb6b 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -383,7 +383,7 @@ int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, case INTEL_OUTPUT_ANALOG: type = DISPLAY_TYPE_CRT; break; - case INTEL_OUTPUT_UNKNOWN: + case INTEL_OUTPUT_DDI: case INTEL_OUTPUT_DP: case INTEL_OUTPUT_HDMI: case INTEL_OUTPUT_DP_MST: diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 7437944b388f..42ec2d1f7a61 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1429,6 +1429,8 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder, u8 val; bool ret; + pipe_config->output_types |= BIT(INTEL_OUTPUT_SDVO); + sdvox = I915_READ(intel_sdvo->sdvo_reg); ret = intel_sdvo_get_input_timing(intel_sdvo, &dtd); diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index a79a7591b2cf..b18609cebe03 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -868,6 +868,8 @@ static void intel_tv_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { + pipe_config->output_types |= BIT(INTEL_OUTPUT_TVOUT); + pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock; }