[Intel-gfx] [PATCH 2/2] drm/i915: sdvo: check GPIOA for SDVO DDC (vga DDC) when GPIOE fails
Dave Airlie
airlied at gmail.com
Mon Jun 15 07:34:14 CEST 2009
On Mon, Jun 15, 2009 at 10:48 AM, Dave Airlie<airlied at linux.ie> wrote:
> On Sun, 14 Jun 2009, Keith Packard wrote:
>
>> Mac Mini's have a single GPIO line on the DVI connector, shared between the
>> analog link and the digital link. So, if DDC isn't detected on GPIOE (the
>> usual SDVO DDC link), try GPIOA (the usual VGA DDC link) when there isn't a
>> VGA monitor connected.
>
> Really kms can't handle this case properly without doing
> workarounds/hacks.
I meant to say kms *can* handle this.
Dave.
>
> 1. Add a DVI-I connector when you get DMI for the Mac Mini. (since it has
> a DVI-I connector)
> 2. Wire up the connector DDC to the analog pins since we know this
> 3. Hook up an SDVO and an analog encoder to this.
> 4. add a function that uses EDID to tell if its analog or digitial (and
> fallbacks to the analog load detect, and maybe use HPD)
>
> You mighr still need to keep ddc and sdvo i2c buses separate but I see no
> major issues doing that.
>
> Dave.
>
>>
>> Signed-off-by: Keith Packard <keithp at keithp.com>
>> ---
>> drivers/gpu/drm/i915/intel_sdvo.c | 89 ++++++++++++++++++++++++++++---------
>> 1 files changed, 67 insertions(+), 22 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
>> index c4d06ff..9a5ab6f 100644
>> --- a/drivers/gpu/drm/i915/intel_sdvo.c
>> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
>> @@ -96,6 +96,9 @@ struct intel_sdvo_priv {
>> /* DDC bus used by this SDVO output */
>> uint8_t ddc_bus;
>>
>> + /* Mac mini hack -- use the same DDC as the analog connector */
>> + struct i2c_adapter *analog_ddc_bus;
>> +
>> int save_sdvo_mult;
>> u16 save_active_outputs;
>> struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
>> @@ -1361,6 +1364,33 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
>> intel_sdvo_read_response(intel_output, &response, 2);
>> }
>>
>> +static struct drm_connector *
>> +intel_find_analog_connector(struct drm_device *dev)
>> +{
>> + struct drm_connector *connector;
>> + struct intel_output *intel_output;
>> + list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
>> + intel_output = to_intel_output(connector);
>> + if (intel_output->type == INTEL_OUTPUT_ANALOG)
>> + return connector;
>> + }
>> + return NULL;
>> +}
>> +
>> +static int
>> +intel_analog_is_connected(struct drm_device *dev)
>> +{
>> + struct drm_connector *analog_connector;
>> + analog_connector = intel_find_analog_connector(dev);
>> +
>> + if (!analog_connector)
>> + return false;
>> + if (analog_connector->funcs->detect(analog_connector) ==
>> + connector_status_disconnected)
>> + return false;
>> + return true;
>> +}
>> +
>> static void
>> intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
>> {
>> @@ -1370,6 +1400,11 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
>>
>> edid = drm_get_edid(&intel_output->base,
>> intel_output->ddc_bus);
>> + if (edid == NULL &&
>> + sdvo_priv->analog_ddc_bus &&
>> + !intel_analog_is_connected(intel_output->base.dev))
>> + edid = drm_get_edid(&intel_output->base,
>> + sdvo_priv->analog_ddc_bus);
>> if (edid != NULL) {
>> sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid);
>> kfree(edid);
>> @@ -1401,31 +1436,33 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
>> static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
>> {
>> struct intel_output *intel_output = to_intel_output(connector);
>> + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
>> + int num_modes;
>>
>> /* set the bus switch and get the modes */
>> - intel_ddc_get_modes(intel_output);
>> + num_modes = intel_ddc_get_modes(intel_output);
>>
>> -#if 0
>> - struct drm_device *dev = encoder->dev;
>> - struct drm_i915_private *dev_priv = dev->dev_private;
>> - /* Mac mini hack. On this device, I get DDC through the analog, which
>> - * load-detects as disconnected. I fail to DDC through the SDVO DDC,
>> - * but it does load-detect as connected. So, just steal the DDC bits
>> - * from analog when we fail at finding it the right way.
>> + /*
>> + * Mac mini hack. On this device, the DVI-I connector shares one DDC
>> + * link between analog and digital outputs. So, if the regular SDVO
>> + * DDC fails, check to see if the analog output is disconnected, in which
>> + * case we'll look there for the digital DDC data.
>> */
>> - crt = xf86_config->output[0];
>> - intel_output = crt->driver_private;
>> - if (intel_output->type == I830_OUTPUT_ANALOG &&
>> - crt->funcs->detect(crt) == XF86OutputStatusDisconnected) {
>> - I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A");
>> - edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus);
>> - xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true);
>> - }
>> - if (edid_mon) {
>> - xf86OutputSetEDID(output, edid_mon);
>> - modes = xf86OutputGetEDIDModes(output);
>> + if (num_modes == 0 &&
>> + sdvo_priv->analog_ddc_bus &&
>> + !intel_analog_is_connected(intel_output->base.dev))
>> + {
>> + struct i2c_adapter *digital_ddc_bus;
>> +
>> + /* Switch to the analog ddc bus and try that
>> + */
>> + digital_ddc_bus = intel_output->ddc_bus;
>> + intel_output->ddc_bus = sdvo_priv->analog_ddc_bus;
>> +
>> + (void) intel_ddc_get_modes(intel_output);
>> +
>> + intel_output->ddc_bus = digital_ddc_bus;
>> }
>> -#endif
>> }
>>
>> /**
>> @@ -1592,11 +1629,14 @@ static int intel_sdvo_get_modes(struct drm_connector *connector)
>> static void intel_sdvo_destroy(struct drm_connector *connector)
>> {
>> struct intel_output *intel_output = to_intel_output(connector);
>> + struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
>>
>> if (intel_output->i2c_bus)
>> intel_i2c_destroy(intel_output->i2c_bus);
>> if (intel_output->ddc_bus)
>> intel_i2c_destroy(intel_output->ddc_bus);
>> + if (sdvo_priv->analog_ddc_bus)
>> + intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
>>
>> drm_sysfs_connector_remove(connector);
>> drm_connector_cleanup(connector);
>> @@ -1821,10 +1861,13 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
>> }
>>
>> /* setup the DDC bus. */
>> - if (output_device == SDVOB)
>> + if (output_device == SDVOB) {
>> intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
>> - else
>> + sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, "SDVOB/VGA DDC BUS");
>> + } else {
>> intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
>> + sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, "SDVOC/VGA DDC BUS");
>> + }
>>
>> if (intel_output->ddc_bus == NULL)
>> goto err_i2c;
>> @@ -1949,6 +1992,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
>> return true;
>>
>> err_i2c:
>> + if (sdvo_priv->analog_ddc_bus != NULL)
>> + intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
>> if (intel_output->ddc_bus != NULL)
>> intel_i2c_destroy(intel_output->ddc_bus);
>> if (intel_output->i2c_bus != NULL)
>>
>
> ------------------------------------------------------------------------------
> Crystal Reports - New Free Runtime and 30 Day Trial
> Check out the new simplified licensing option that enables unlimited
> royalty-free distribution of the report engine for externally facing
> server and web deployment.
> http://p.sf.net/sfu/businessobjects
> --
> _______________________________________________
> Dri-devel mailing list
> Dri-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/dri-devel
>
More information about the Intel-gfx
mailing list