On Mon, Jun 15, 2009 at 10:48 AM, Dave Airlie<airl...@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 <kei...@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@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/dri-devel > ------------------------------------------------------------------------------ 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@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel