drivers/gpu/drm/openchrome/via_analog.c | 90 ++++++++++++++++++++++++++++++- drivers/gpu/drm/openchrome/via_display.c | 2 drivers/gpu/drm/openchrome/via_display.h | 1 drivers/gpu/drm/openchrome/via_drv.h | 3 - 4 files changed, 93 insertions(+), 3 deletions(-)
New commits: commit 7bbc9a8b4e02ea643d970c26185b607ef4ae5135 Author: Kevin Brace <kevinbr...@gmx.com> Date: Tue Feb 13 08:26:13 2018 -0800 drm/openchrome: Version bumped to 3.0.76 Adds I2C bus 2 support for analog (VGA) output. This will now allow DVI to VGA passive converter to work properly in most cases. Signed-off-by: Kevin Brace <kevinbr...@gmx.com> diff --git a/drivers/gpu/drm/openchrome/via_drv.h b/drivers/gpu/drm/openchrome/via_drv.h index 426a5d4d3751..070599f2c8a8 100644 --- a/drivers/gpu/drm/openchrome/via_drv.h +++ b/drivers/gpu/drm/openchrome/via_drv.h @@ -34,7 +34,7 @@ #define DRIVER_MAJOR 3 #define DRIVER_MINOR 0 -#define DRIVER_PATCHLEVEL 75 +#define DRIVER_PATCHLEVEL 76 #include <linux/module.h> commit fc30c233ce774a331cd6f34a2252f7fe0e42df12 Author: Kevin Brace <kevinbr...@gmx.com> Date: Tue Feb 13 08:21:44 2018 -0800 drm/openchrome: Add I2C bus 2 support for analog (VGA) output Many DVI connectors are DVI-I type and analog signals come out of a DVI-I connector. However, in many cases its I2C bus used is I2C bus 2, but the support code for I2C bus 2 support with analog (VGA) output was previously missing. This commit will now allow DVI to VGA passive converter to work properly in most cases. Signed-off-by: Kevin Brace <kevinbr...@gmx.com> diff --git a/drivers/gpu/drm/openchrome/via_analog.c b/drivers/gpu/drm/openchrome/via_analog.c index 960b8eea2618..f113aa959675 100644 --- a/drivers/gpu/drm/openchrome/via_analog.c +++ b/drivers/gpu/drm/openchrome/via_analog.c @@ -238,9 +238,28 @@ via_analog_detect(struct drm_connector *connector, bool force) edid); kfree(edid); ret = connector_status_connected; + goto exit; } } + if (con->i2c_bus & VIA_I2C_BUS2) { + i2c_bus = via_find_ddc_bus(0x31); + } else { + i2c_bus = NULL; + } + + if (i2c_bus) { + edid = drm_get_edid(&con->base, i2c_bus); + if (edid) { + drm_mode_connector_update_edid_property(connector, + edid); + kfree(edid); + ret = connector_status_connected; + goto exit; + } + } + +exit: DRM_DEBUG_KMS("Exiting %s.\n", __func__); return ret; } @@ -274,9 +293,26 @@ static int via_analog_get_modes(struct drm_connector *connector) if (edid) { count = drm_add_edid_modes(connector, edid); kfree(edid); + goto exit; + } + } + + if (con->i2c_bus & VIA_I2C_BUS2) { + i2c_bus = via_find_ddc_bus(0x31); + } else { + i2c_bus = NULL; + } + + if (i2c_bus) { + edid = drm_get_edid(&con->base, i2c_bus); + if (edid) { + count = drm_add_edid_modes(connector, edid); + kfree(edid); + goto exit; } } +exit: DRM_DEBUG_KMS("Exiting %s.\n", __func__); return count; } @@ -287,14 +323,64 @@ static const struct drm_connector_helper_funcs via_analog_connector_helper_funcs .best_encoder = via_best_encoder, }; +void via_analog_probe(struct drm_device *dev) +{ + struct via_device *dev_priv = dev->dev_private; + u16 chipset = dev->pdev->device; + u8 sr13, sr5a; + + DRM_DEBUG_KMS("Entered %s.\n", __func__); + + switch (chipset) { + case PCI_DEVICE_ID_VIA_VT3157: + case PCI_DEVICE_ID_VIA_VT1122: + case PCI_DEVICE_ID_VIA_VX875: + case PCI_DEVICE_ID_VIA_VX900_VGA: + sr5a = vga_rseq(VGABASE, 0x5a); + DRM_DEBUG_KMS("SR5A: 0x%02x\n", sr5a); + + /* Setting SR5A[0] to 1. + * This allows the reading out the alternative + * pin strapping information from SR12 and SR13. */ + svga_wseq_mask(VGABASE, 0x5a, BIT(0), BIT(0)); + DRM_DEBUG_KMS("SR5A: 0x%02x\n", sr5a); + + sr13 = vga_rseq(VGABASE, 0x13); + DRM_DEBUG_KMS("SR13: 0x%02x\n", sr13); + + if (!(sr13 & BIT(2))) { + dev_priv->analog_presence = true; + DRM_DEBUG_KMS("Detected the presence of VGA.\n"); + } else { + dev_priv->analog_presence = false; + } + + /* Restore SR5A. */ + vga_wseq(VGABASE, 0x5a, sr5a); + break; + default: + dev_priv->analog_presence = true; + DRM_DEBUG_KMS("Detected the presence of VGA.\n"); + break; + } + + dev_priv->analog_i2c_bus = VIA_I2C_NONE; + + if (dev_priv->analog_presence) { + dev_priv->analog_i2c_bus = VIA_I2C_BUS2 | VIA_I2C_BUS1; + } + + dev_priv->mapped_i2c_bus |= dev_priv->analog_i2c_bus; + + DRM_DEBUG_KMS("Exiting %s.\n", __func__); +} + void via_analog_init(struct drm_device *dev) { struct via_connector *con; struct via_encoder *enc; struct via_device *dev_priv = dev->dev_private; - dev_priv->analog_i2c_bus = VIA_I2C_BUS1; - enc = kzalloc(sizeof(*enc) + sizeof(*con), GFP_KERNEL); if (!enc) { DRM_ERROR("Failed to allocate connector and encoder\n"); diff --git a/drivers/gpu/drm/openchrome/via_display.c b/drivers/gpu/drm/openchrome/via_display.c index 8cdca0ce81b6..df104e6f9172 100644 --- a/drivers/gpu/drm/openchrome/via_display.c +++ b/drivers/gpu/drm/openchrome/via_display.c @@ -508,6 +508,8 @@ via_modeset_init(struct drm_device *dev) via_fp_probe(dev); + via_analog_probe(dev); + via_tmds_init(dev); diff --git a/drivers/gpu/drm/openchrome/via_display.h b/drivers/gpu/drm/openchrome/via_display.h index 938719b6ccd9..5aee32723bca 100644 --- a/drivers/gpu/drm/openchrome/via_display.h +++ b/drivers/gpu/drm/openchrome/via_display.h @@ -182,6 +182,7 @@ extern int via_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode); extern void via_connector_destroy(struct drm_connector *connector); +extern void via_analog_probe(struct drm_device *dev); extern void via_tmds_probe(struct drm_device *dev); extern void via_fp_probe(struct drm_device *dev); diff --git a/drivers/gpu/drm/openchrome/via_drv.h b/drivers/gpu/drm/openchrome/via_drv.h index d4e812e3ad57..426a5d4d3751 100644 --- a/drivers/gpu/drm/openchrome/via_drv.h +++ b/drivers/gpu/drm/openchrome/via_drv.h @@ -209,6 +209,7 @@ struct via_device { * is needed for properly controlling its FP. */ bool is_quanta_il1; + bool analog_presence; u32 analog_i2c_bus; bool int_tmds_presence; _______________________________________________ Openchrome-devel mailing list Openchrome-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/openchrome-devel