Message ID | 1397496369-2746-3-git-send-email-eich@suse.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, Apr 14, 2014 at 07:26:09PM +0200, Egbert Eich wrote: > Depending on the SDVO output_flags SDVO may have multiple connectors. > These are all initialized in intel_sdvo_output_setup(). The connector > that is initialized later will override the encoder_type that has been > set up by an earlier connector type initialization. Eventually the > one that comes last wins. > Eventually when intel_sdvo_detect() is called the active connector is > determined. > Delay encoder type initialization until the active connector is known > and set it to the type that corresponds to this connector. > > Signed-off-by: Egbert Eich <eich@suse.de> Please kill the redundant encoder->encoder_type = DRM_MODE_ENCODER_NONE as I think that will help clarify that during init we set the intel_sdvo->type and then during the detection of the actual connected output we assign the encoder_type. Otherwise, lgtm. -Chris
On Mon, Apr 14, 2014 at 07:26:09PM +0200, Egbert Eich wrote: > Depending on the SDVO output_flags SDVO may have multiple connectors. > These are all initialized in intel_sdvo_output_setup(). The connector > that is initialized later will override the encoder_type that has been > set up by an earlier connector type initialization. Eventually the > one that comes last wins. > Eventually when intel_sdvo_detect() is called the active connector is > determined. > Delay encoder type initialization until the active connector is known > and set it to the type that corresponds to this connector. > > Signed-off-by: Egbert Eich <eich@suse.de> Hm, has this any effect on the code itself? I think if we want to fix this just for optics we should add a new DRM_MODE_ENCODER_MULTI. At least I have an sdvo here which has a dac, hdmi and tv-out ... This also reminds that I should finally polish of the multi-sdvo fixes I have around here - currently the last encoder detected wins on a multi-encoder chip, which means if you have an lvds+hdmi combo and plug in a screeen you'll never be able to use the lvds again until the hdmi is unplugged. Much worse if there's a tv-out detect issue ;-) Cheers, Daniel > --- > drivers/gpu/drm/i915/intel_sdvo.c | 23 ++++++++++++++++++----- > 1 file changed, 18 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c > index d27155a..5043f16 100644 > --- a/drivers/gpu/drm/i915/intel_sdvo.c > +++ b/drivers/gpu/drm/i915/intel_sdvo.c > @@ -154,6 +154,9 @@ struct intel_sdvo_connector { > /* Mark the type of connector */ > uint16_t output_flag; > > + /* store encoder type for convenience */ > + int encoder_type; > + > enum hdmi_force_audio force_audio; > > /* This contains all current supported TV format */ > @@ -1746,6 +1749,7 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) > if (response == 0) > return connector_status_disconnected; > > + intel_sdvo->base.base.encoder_type = intel_sdvo_connector->encoder_type; > intel_sdvo->attached_output = response; > > intel_sdvo->has_hdmi_monitor = false; > @@ -2489,7 +2493,9 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) > } else { > intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; > } > - encoder->encoder_type = DRM_MODE_ENCODER_TMDS; > + /* delay encoder_type setting until detection */ > + intel_sdvo_connector->encoder_type = DRM_MODE_ENCODER_TMDS; > + encoder->encoder_type = DRM_MODE_ENCODER_NONE; > connector->connector_type = DRM_MODE_CONNECTOR_DVID; > > if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) { > @@ -2524,7 +2530,9 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) > > intel_connector = &intel_sdvo_connector->base; > connector = &intel_connector->base; > - encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; > + /* delay encoder_type setting until detection */ > + intel_sdvo_connector->encoder_type = DRM_MODE_ENCODER_TVDAC; > + encoder->encoder_type = DRM_MODE_ENCODER_NONE; > connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; > > intel_sdvo->controlled_output |= type; > @@ -2568,7 +2576,9 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) > intel_connector = &intel_sdvo_connector->base; > connector = &intel_connector->base; > intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT; > - encoder->encoder_type = DRM_MODE_ENCODER_DAC; > + /* delay encoder_type setting until detection */ > + intel_sdvo_connector->encoder_type = DRM_MODE_ENCODER_DAC; > + encoder->encoder_type = DRM_MODE_ENCODER_NONE; > connector->connector_type = DRM_MODE_CONNECTOR_VGA; > > if (device == 0) { > @@ -2603,7 +2613,9 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) > > intel_connector = &intel_sdvo_connector->base; > connector = &intel_connector->base; > - encoder->encoder_type = DRM_MODE_ENCODER_LVDS; > + /* delay encoder_type setting until detection */ > + intel_sdvo_connector->encoder_type = DRM_MODE_ENCODER_LVDS; > + encoder->encoder_type = DRM_MODE_ENCODER_NONE; > connector->connector_type = DRM_MODE_CONNECTOR_LVDS; > > if (device == 0) { > @@ -2984,7 +2996,8 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) > /* encoder type will be decided later */ > intel_encoder = &intel_sdvo->base; > intel_encoder->type = INTEL_OUTPUT_SDVO; > - drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0); > + drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, > + DRM_MODE_ENCODER_NONE); > > /* Read the regs to test if we can talk to the device */ > for (i = 0; i < 0x40; i++) { > -- > 1.8.4.5 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Daniel Vetter writes: > On Mon, Apr 14, 2014 at 07:26:09PM +0200, Egbert Eich wrote: > > Depending on the SDVO output_flags SDVO may have multiple connectors. > > These are all initialized in intel_sdvo_output_setup(). The connector > > that is initialized later will override the encoder_type that has been > > set up by an earlier connector type initialization. Eventually the > > one that comes last wins. > > Eventually when intel_sdvo_detect() is called the active connector is > > determined. > > Delay encoder type initialization until the active connector is known > > and set it to the type that corresponds to this connector. > > > > Signed-off-by: Egbert Eich <eich@suse.de> > > Hm, has this any effect on the code itself? I think if we want to fix this > just for optics we should add a new DRM_MODE_ENCODER_MULTI. At least I > have an sdvo here which has a dac, hdmi and tv-out ... With the present logic the last connector in the list matching a flag bit will win the encoder type. The encoder type is presently just used for (debug) messages, so it is cosmetic. > > This also reminds that I should finally polish of the multi-sdvo fixes I > have around here - currently the last encoder detected wins on a > multi-encoder chip, which means if you have an lvds+hdmi combo and plug in > a screeen you'll never be able to use the lvds again until the hdmi is > unplugged. You know, from looking at the code I was wondering already if this was possible at all. I stayed away tinkering with this - there doesn't seem to be documentation on the SDVO command set publically available. Moreover I'm moslty dealing with cash registers here - so I doubt they have all the SVIDEO connectors they advertise ;) But I can't tell as I don't even have physical access! As I read the current code it seems like bad things could happen if more than one bit is set in intel_sdvo->attached_output: after all tv-out should have quite different timing requirements than a TMDS. > > Much worse if there's a tv-out detect issue ;-) ;p Cheers, Egbert. > > Cheers, Daniel > > > --- > > drivers/gpu/drm/i915/intel_sdvo.c | 23 ++++++++++++++++++----- > > 1 file changed, 18 insertions(+), 5 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c > > index d27155a..5043f16 100644 > > --- a/drivers/gpu/drm/i915/intel_sdvo.c > > +++ b/drivers/gpu/drm/i915/intel_sdvo.c > > @@ -154,6 +154,9 @@ struct intel_sdvo_connector { > > /* Mark the type of connector */ > > uint16_t output_flag; > > > > + /* store encoder type for convenience */ > > + int encoder_type; > > + > > enum hdmi_force_audio force_audio; > > > > /* This contains all current supported TV format */ > > @@ -1746,6 +1749,7 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) > > if (response == 0) > > return connector_status_disconnected; > > > > + intel_sdvo->base.base.encoder_type = intel_sdvo_connector->encoder_type; > > intel_sdvo->attached_output = response; > > > > intel_sdvo->has_hdmi_monitor = false; > > @@ -2489,7 +2493,9 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) > > } else { > > intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; > > } > > - encoder->encoder_type = DRM_MODE_ENCODER_TMDS; > > + /* delay encoder_type setting until detection */ > > + intel_sdvo_connector->encoder_type = DRM_MODE_ENCODER_TMDS; > > + encoder->encoder_type = DRM_MODE_ENCODER_NONE; > > connector->connector_type = DRM_MODE_CONNECTOR_DVID; > > > > if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) { > > @@ -2524,7 +2530,9 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) > > > > intel_connector = &intel_sdvo_connector->base; > > connector = &intel_connector->base; > > - encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; > > + /* delay encoder_type setting until detection */ > > + intel_sdvo_connector->encoder_type = DRM_MODE_ENCODER_TVDAC; > > + encoder->encoder_type = DRM_MODE_ENCODER_NONE; > > connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; > > > > intel_sdvo->controlled_output |= type; > > @@ -2568,7 +2576,9 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) > > intel_connector = &intel_sdvo_connector->base; > > connector = &intel_connector->base; > > intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT; > > - encoder->encoder_type = DRM_MODE_ENCODER_DAC; > > + /* delay encoder_type setting until detection */ > > + intel_sdvo_connector->encoder_type = DRM_MODE_ENCODER_DAC; > > + encoder->encoder_type = DRM_MODE_ENCODER_NONE; > > connector->connector_type = DRM_MODE_CONNECTOR_VGA; > > > > if (device == 0) { > > @@ -2603,7 +2613,9 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) > > > > intel_connector = &intel_sdvo_connector->base; > > connector = &intel_connector->base; > > - encoder->encoder_type = DRM_MODE_ENCODER_LVDS; > > + /* delay encoder_type setting until detection */ > > + intel_sdvo_connector->encoder_type = DRM_MODE_ENCODER_LVDS; > > + encoder->encoder_type = DRM_MODE_ENCODER_NONE; > > connector->connector_type = DRM_MODE_CONNECTOR_LVDS; > > > > if (device == 0) { > > @@ -2984,7 +2996,8 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) > > /* encoder type will be decided later */ > > intel_encoder = &intel_sdvo->base; > > intel_encoder->type = INTEL_OUTPUT_SDVO; > > - drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0); > > + drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, > > + DRM_MODE_ENCODER_NONE); > > > > /* Read the regs to test if we can talk to the device */ > > for (i = 0; i < 0x40; i++) { > > -- > > 1.8.4.5 > > > > _______________________________________________ > > Intel-gfx mailing list > > Intel-gfx@lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx > > -- > Daniel Vetter > Software Engineer, Intel Corporation > +41 (0) 79 365 57 48 - http://blog.ffwll.ch
On Wed, Apr 16, 2014 at 07:58:48AM +0200, Egbert Eich wrote: > Daniel Vetter writes: > > On Mon, Apr 14, 2014 at 07:26:09PM +0200, Egbert Eich wrote: > > > Depending on the SDVO output_flags SDVO may have multiple connectors. > > > These are all initialized in intel_sdvo_output_setup(). The connector > > > that is initialized later will override the encoder_type that has been > > > set up by an earlier connector type initialization. Eventually the > > > one that comes last wins. > > > Eventually when intel_sdvo_detect() is called the active connector is > > > determined. > > > Delay encoder type initialization until the active connector is known > > > and set it to the type that corresponds to this connector. > > > > > > Signed-off-by: Egbert Eich <eich@suse.de> > > > > Hm, has this any effect on the code itself? I think if we want to fix this > > just for optics we should add a new DRM_MODE_ENCODER_MULTI. At least I > > have an sdvo here which has a dac, hdmi and tv-out ... > > With the present logic the last connector in the list matching a flag bit > will win the encoder type. The encoder type is presently just used for > (debug) messages, so it is cosmetic. I'm vary of changing the encoder type at runtime tbh. We use the same hack in intel_ddi.c to switch between hdmi and dp mode, and the results aren't pretty imo. For debug output imo adding a new "multi" encoder type is better. And if we need the type somehow to set up the right connector for sdvo encoders with more than one detected output, then we need to track this piece of state somewhere in our modeset state (either with the connector->encoder links or with a bit of state in the pipe config structure). Which also means we need state read-out and cross-check support to make sure it really does what we want. Storing such state in global structure tends to lead to subtile bugs and prevent proper pre-compute/commit semantics for modeset changes. -Daniel
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d27155a..5043f16 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -154,6 +154,9 @@ struct intel_sdvo_connector { /* Mark the type of connector */ uint16_t output_flag; + /* store encoder type for convenience */ + int encoder_type; + enum hdmi_force_audio force_audio; /* This contains all current supported TV format */ @@ -1746,6 +1749,7 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) if (response == 0) return connector_status_disconnected; + intel_sdvo->base.base.encoder_type = intel_sdvo_connector->encoder_type; intel_sdvo->attached_output = response; intel_sdvo->has_hdmi_monitor = false; @@ -2489,7 +2493,9 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) } else { intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; } - encoder->encoder_type = DRM_MODE_ENCODER_TMDS; + /* delay encoder_type setting until detection */ + intel_sdvo_connector->encoder_type = DRM_MODE_ENCODER_TMDS; + encoder->encoder_type = DRM_MODE_ENCODER_NONE; connector->connector_type = DRM_MODE_CONNECTOR_DVID; if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) { @@ -2524,7 +2530,9 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) intel_connector = &intel_sdvo_connector->base; connector = &intel_connector->base; - encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; + /* delay encoder_type setting until detection */ + intel_sdvo_connector->encoder_type = DRM_MODE_ENCODER_TVDAC; + encoder->encoder_type = DRM_MODE_ENCODER_NONE; connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; intel_sdvo->controlled_output |= type; @@ -2568,7 +2576,9 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) intel_connector = &intel_sdvo_connector->base; connector = &intel_connector->base; intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT; - encoder->encoder_type = DRM_MODE_ENCODER_DAC; + /* delay encoder_type setting until detection */ + intel_sdvo_connector->encoder_type = DRM_MODE_ENCODER_DAC; + encoder->encoder_type = DRM_MODE_ENCODER_NONE; connector->connector_type = DRM_MODE_CONNECTOR_VGA; if (device == 0) { @@ -2603,7 +2613,9 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) intel_connector = &intel_sdvo_connector->base; connector = &intel_connector->base; - encoder->encoder_type = DRM_MODE_ENCODER_LVDS; + /* delay encoder_type setting until detection */ + intel_sdvo_connector->encoder_type = DRM_MODE_ENCODER_LVDS; + encoder->encoder_type = DRM_MODE_ENCODER_NONE; connector->connector_type = DRM_MODE_CONNECTOR_LVDS; if (device == 0) { @@ -2984,7 +2996,8 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) /* encoder type will be decided later */ intel_encoder = &intel_sdvo->base; intel_encoder->type = INTEL_OUTPUT_SDVO; - drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0); + drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, + DRM_MODE_ENCODER_NONE); /* Read the regs to test if we can talk to the device */ for (i = 0; i < 0x40; i++) {
Depending on the SDVO output_flags SDVO may have multiple connectors. These are all initialized in intel_sdvo_output_setup(). The connector that is initialized later will override the encoder_type that has been set up by an earlier connector type initialization. Eventually the one that comes last wins. Eventually when intel_sdvo_detect() is called the active connector is determined. Delay encoder type initialization until the active connector is known and set it to the type that corresponds to this connector. Signed-off-by: Egbert Eich <eich@suse.de> --- drivers/gpu/drm/i915/intel_sdvo.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)