[Intel-gfx] [PATCH 1/2] drm/i915: introduce pipe_config->ddi_personality
Paulo Zanoni
przanoni at gmail.com
Tue Oct 28 14:26:51 CET 2014
2014-10-28 5:49 GMT-02:00 Daniel Vetter <daniel at ffwll.ch>:
> On Mon, Oct 27, 2014 at 05:47:51PM -0200, Paulo Zanoni wrote:
>> From: Paulo Zanoni <paulo.r.zanoni at intel.com>
>>
>> On HSW+, one encoder (DDI) can have multiple connectors (HDMI and DP).
>> If no connector is connected, we consider the encoder type to be
>> INTEL_OUTPUT_UNKNOWN. The problem is that we allow user space to set
>> modes on disconnected connectors, so when we try to set a mode on an
>> INTEL_OUTPUT_UNKNOWN connector, we don't know what to do and end up
>> printing a WARN. So on this patch, we introduce
>> pipe_config->ddi_personality to help with that.
>>
>> When the user space sets a mode on a connector, we check the connector
>> type and match it against intel_encoder->type and set the DDI
>> personality accordingly. Then, after the compute config stage is over,
>> we properly assign the personality to intel_encoder->type.
>>
>> This patch was previously called "drm/i915: Set the digital port
>> encoder personality during modeset".
>>
>> References: http://patchwork.freedesktop.org/patch/17838/
>> Testcase: igt/kms_setmode/clone-exclusive-crtc
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=68463
>> Credits-to: Damien Lespiau <damien.lespiau at intel.com> (for the
>> previous versions of the patch).
>> Cc: Damien Lespiau <damien.lespiau at intel.com>
>> Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
>> Signed-off-by: Paulo Zanoni <paulo.r.zanoni at intel.com>
>> ---
>> drivers/gpu/drm/i915/intel_ddi.c | 97 ++++++++++++++++++++++++++++++++++--
>> drivers/gpu/drm/i915/intel_display.c | 2 +
>> drivers/gpu/drm/i915/intel_drv.h | 4 ++
>> 3 files changed, 100 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
>> index cb5367c..5cdc2f4 100644
>> --- a/drivers/gpu/drm/i915/intel_ddi.c
>> +++ b/drivers/gpu/drm/i915/intel_ddi.c
>> @@ -1557,18 +1557,109 @@ static void intel_ddi_destroy(struct drm_encoder *encoder)
>> intel_dp_encoder_destroy(encoder);
>> }
>>
>> +static bool intel_ddi_set_personality(struct intel_encoder *encoder,
>> + struct intel_crtc_config *pipe_config)
>> +{
>> + struct drm_device *dev = encoder->base.dev;
>> + struct intel_connector *connector;
>> + int connectors = 0;
>> + enum port port = intel_ddi_get_encoder_port(encoder);
>> +
>> + list_for_each_entry(connector, &dev->mode_config.connector_list,
>> + base.head) {
>> +
>> + if (connector->new_encoder != encoder)
>> + continue;
>> +
>> + connectors++;
>> + if (WARN_ON(connectors > 1))
>> + return false;
>> +
>> + switch (connector->base.connector_type) {
>> + case DRM_MODE_CONNECTOR_HDMIA:
>> + case DRM_MODE_CONNECTOR_HDMIB:
>> + pipe_config->ddi_personality = INTEL_OUTPUT_HDMI;
>> + break;
>> + case DRM_MODE_CONNECTOR_DisplayPort:
>> + pipe_config->ddi_personality = INTEL_OUTPUT_DISPLAYPORT;
>> + break;
>> + case DRM_MODE_CONNECTOR_eDP:
>> + pipe_config->ddi_personality = INTEL_OUTPUT_EDP;
>> + break;
>> + default:
>> + WARN(1, "DRM connector type %d\n",
>> + connector->base.connector_type);
>> + return false;
>> + }
>> +
>> + if (encoder->type == pipe_config->ddi_personality)
>> + continue;
>> +
>> + /* We expect eDP to always have encoder->type correctly set, so
>> + * it shouldn't reach this point. */
>> + if (pipe_config->ddi_personality == INTEL_OUTPUT_EDP) {
>> + DRM_ERROR("DDI %c, type %s marked as eDP\n",
>> + port_name(port),
>> + intel_output_name(encoder->type));
>> + return false;
>> + }
>> +
>> + /*
>> + * We can't change the DDI type if we already have a connected
>> + * device on this port. The first time a DDI is used though
>> + * (encoder_type is INTEL_OUTPUT_UNKNOWN) and we force a
>> + * connector to be connected (either trought the kernel command
>> + * line or KMS) we need to comply.
>> + */
>> + if (encoder->type != INTEL_OUTPUT_UNKNOWN &&
>> + connector->base.status == connector_status_connected) {
>> + DRM_DEBUG_KMS("Can't set DDI %c personality to %s, it has a connected %s device\n",
>> + port_name(port),
>> + intel_output_name(encoder->type),
>> + intel_output_name(pipe_config->ddi_personality));
>> + return false;
>> + }
>
> I think this part is better done with Ville's more general "do we have
> both hdmi and dp on the same dig_port?" check. Care to review Ville's
> patch instead? Thomas Wood is signed up for it on the review board but I
> guess you can steal that task.
Ville's patch solves a different problem. I just reviewed it, but we
still need the check above. The code above is in case, for example,
there's a DP connector actually connected (but without a mode set),
and then the user tries to set a mode on the HDMI connector of this
encoder.
>
>> +
>> + DRM_DEBUG_KMS("Setting DDI %c personality to %s\n",
>> + port_name(port),
>> + intel_output_name(pipe_config->ddi_personality));
>> + }
>> +
>> + return true;
>> +
>> +}
>> +
>> +void intel_ddi_commit_personality(struct intel_crtc *crtc)
>> +{
>> + struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(&crtc->base);
>> +
>> + switch (encoder->type) {
>> + case INTEL_OUTPUT_HDMI:
>> + case INTEL_OUTPUT_DISPLAYPORT:
>> + case INTEL_OUTPUT_EDP:
>> + case INTEL_OUTPUT_UNKNOWN:
>> + encoder->type = crtc->config.ddi_personality;
>> + break;
>> + case INTEL_OUTPUT_ANALOG:
>> + break;
>> + default:
>> + WARN(1, "Output type %s\n", intel_output_name(encoder->type));
>> + break;
>> + }
>> +}
>> +
>> static bool intel_ddi_compute_config(struct intel_encoder *encoder,
>> struct intel_crtc_config *pipe_config)
>> {
>> - int type = encoder->type;
>> int port = intel_ddi_get_encoder_port(encoder);
>>
>> - WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
>> + if (!intel_ddi_set_personality(encoder, pipe_config))
>> + return false;
>>
>> if (port == PORT_A)
>> pipe_config->cpu_transcoder = TRANSCODER_EDP;
>>
>> - if (type == INTEL_OUTPUT_HDMI)
>> + if (pipe_config->ddi_personality == INTEL_OUTPUT_HDMI)
>> return intel_hdmi_compute_config(encoder, pipe_config);
>> else
>> return intel_dp_compute_config(encoder, pipe_config);
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index b5dbc88..16750c4 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -7810,6 +7810,8 @@ static int haswell_crtc_mode_set(struct intel_crtc *crtc,
>> int x, int y,
>> struct drm_framebuffer *fb)
>> {
>> + intel_ddi_commit_personality(crtc);
>
> This will conflict with Ander's in-flight patches to completely remove the
> modeset callback. But I'm not really sure
>
> Also I'm not sure whether we should keep updating encoder->type now that
> we have ddi_personality - tracking the same state in two places usually
> leads to bugs. Imo it's better to switch all existing encoder->type checks
> in the ddi code over to check config->ddi_personality. We might need a
> prep patch to also set the ddi_personality to FDI for the vga output on
> hsw. Thinking about this, a separate enum might look pretty for this. Or
> just match the bitfield enum of the register.
>
> Also I think we should have state readout support for ddi_personality just
> for paranoia.
> -Daniel
>
>> +
>> if (!intel_ddi_pll_select(crtc))
>> return -EINVAL;
>>
>> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>> index 5ab813c..bf3267c 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -386,6 +386,9 @@ struct intel_crtc_config {
>>
>> bool dp_encoder_is_mst;
>> int pbn;
>> +
>> + /* This should be INTEL_OUTPUT_*. */
>> + int ddi_personality;
>> };
>>
>> struct intel_pipe_wm {
>> @@ -817,6 +820,7 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder);
>> void intel_ddi_clock_get(struct intel_encoder *encoder,
>> struct intel_crtc_config *pipe_config);
>> void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state);
>> +void intel_ddi_commit_personality(struct intel_crtc *crtc);
>>
>> /* intel_frontbuffer.c */
>> void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj,
>> --
>> 2.1.1
>>
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
--
Paulo Zanoni
More information about the Intel-gfx
mailing list