drivers/gpu/drm/openchrome/via_drv.h |    4 
 drivers/gpu/drm/openchrome/via_fp.c  |  176 +++++++++++++++++++++++++----------
 2 files changed, 130 insertions(+), 50 deletions(-)

New commits:
commit 966e216ada5f104e2a3086949febe07fee9b9a1c
Author: Kevin Brace <kevinbr...@gmx.com>
Date:   Fri Mar 9 11:37:36 2018 -0800

    drm/openchrome: Version bumped to 3.0.78
    
    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 2141edf4edf2..df2eb0a4f36d 100644
--- a/drivers/gpu/drm/openchrome/via_drv.h
+++ b/drivers/gpu/drm/openchrome/via_drv.h
@@ -30,11 +30,11 @@
 #define DRIVER_AUTHOR       "OpenChrome Project"
 #define DRIVER_NAME         "openchrome"
 #define DRIVER_DESC         "OpenChrome DRM for VIA Technologies Chrome IGP"
-#define DRIVER_DATE         "20180308"
+#define DRIVER_DATE         "20180309"
 
 #define DRIVER_MAJOR           3
 #define DRIVER_MINOR           0
-#define DRIVER_PATCHLEVEL      77
+#define DRIVER_PATCHLEVEL      78
 
 #include <linux/module.h>
 
commit 5a6b549b83816cb62ecff8dac655ed7d6da87f96
Author: Kevin Brace <kevinbr...@gmx.com>
Date:   Fri Mar 9 11:33:03 2018 -0800

    drm/openchrome: Fix for FP detection regression
    
    Some of the code was borrowed from Radeon DRM.
    
    Signed-off-by: Kevin Brace <kevinbr...@gmx.com>

diff --git a/drivers/gpu/drm/openchrome/via_fp.c 
b/drivers/gpu/drm/openchrome/via_fp.c
index f88fe3a4c53b..67ec868af7e6 100644
--- a/drivers/gpu/drm/openchrome/via_fp.c
+++ b/drivers/gpu/drm/openchrome/via_fp.c
@@ -53,6 +53,43 @@ static via_fp_info via_fp_info_table[] = {
        {1600, 1200}
 };
 
+static bool openchrome_fp_probe_edid(struct i2c_adapter *i2c_bus)
+{
+       u8 out = 0x0;
+       u8 buf[8];
+       struct i2c_msg msgs[] = {
+               {
+                       .addr = DDC_ADDR,
+                       .flags = 0,
+                       .len = 1,
+                       .buf = &out,
+               },
+               {
+                       .addr = DDC_ADDR,
+                       .flags = I2C_M_RD,
+                       .len = 8,
+                       .buf = buf,
+               }
+       };
+       int i2c_ret;
+       bool ret = false;
+
+       DRM_DEBUG_KMS("Entered %s.\n", __func__);
+
+       i2c_ret = i2c_transfer(i2c_bus, msgs, 2);
+       if (i2c_ret != 2) {
+               goto exit;
+       }
+
+       if (drm_edid_header_is_valid(buf) < 6) {
+               goto exit;
+       }
+
+       ret = true;
+exit:
+       DRM_DEBUG_KMS("Exiting %s.\n", __func__);
+       return ret;
+}
 
 /* caculate the cetering timing using mode and adjusted_mode */
 static void
@@ -749,43 +786,63 @@ via_fp_detect(struct drm_connector *connector,  bool 
force)
        struct i2c_adapter *i2c_bus;
        struct edid *edid = NULL;
        u8 mask;
+       uint32_t i, i2c_bus_bit;
 
        DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
-       drm_mode_connector_update_edid_property(connector, edid);
-
        if (machine_is_olpc()) {
                ret = connector_status_connected;
                goto exit;
        }
 
-       if (con->i2c_bus & VIA_I2C_BUS2) {
-               i2c_bus = via_find_ddc_bus(0x31);
-       } else if (con->i2c_bus & VIA_I2C_BUS3) {
-               i2c_bus = via_find_ddc_bus(0x2c);
-       } else {
-               i2c_bus = NULL;
-       }
+       i2c_bus_bit = VIA_I2C_BUS2;
+       for (i = 0; i < 2; i++) {
+               if (con->i2c_bus & i2c_bus_bit) {
+                       if (i2c_bus_bit & VIA_I2C_BUS2) {
+                               i2c_bus = via_find_ddc_bus(0x31);
+                       } else if (i2c_bus_bit & VIA_I2C_BUS3) {
+                               i2c_bus = via_find_ddc_bus(0x2c);
+                       } else {
+                               i2c_bus = NULL;
+                               i2c_bus_bit = i2c_bus_bit << 1;
+                               continue;
+                       }
+               } else {
+                       i2c_bus = NULL;
+                       i2c_bus_bit = i2c_bus_bit << 1;
+                       continue;
+               }
+
+               if (!openchrome_fp_probe_edid(i2c_bus)) {
+                       i2c_bus_bit = i2c_bus_bit << 1;
+                       continue;
+               }
 
-       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;
+                       if (edid->input & DRM_EDID_INPUT_DIGITAL) {
+                               ret = connector_status_connected;
+                               kfree(edid);
+                               DRM_DEBUG_KMS("FP detected.\n");
+                               DRM_DEBUG_KMS("i2c_bus_bit: %x\n", i2c_bus_bit);
+                               goto exit;
+                       } else {
+                               kfree(edid);
+                       }
                }
+
+               i2c_bus_bit = i2c_bus_bit << 1;
+       }
+
+       if (connector->dev->pdev->device ==
+                                       PCI_DEVICE_ID_VIA_CLE266) {
+               mask = BIT(3);
        } else {
-               if (connector->dev->pdev->device ==
-                       PCI_DEVICE_ID_VIA_CLE266) {
-                       mask = BIT(3);
-               } else {
-                       mask = BIT(1);
-               }
+               mask = BIT(1);
+       }
 
-               if (vga_rcrt(VGABASE, 0x3B) & mask) {
-                       ret = connector_status_connected;
-               }
+       if (vga_rcrt(VGABASE, 0x3B) & mask) {
+               ret = connector_status_connected;
        }
 
 exit:
@@ -854,6 +911,7 @@ via_fp_get_modes(struct drm_connector *connector)
        u8 reg_value;
        int hdisplay, vdisplay;
        int count = 0;
+       uint32_t i, i2c_bus_bit;
 
        DRM_DEBUG_KMS("Entered %s.\n", __func__);
 
@@ -880,41 +938,63 @@ via_fp_get_modes(struct drm_connector *connector)
                drm_mode_set_name(native_mode);
                drm_mode_probed_add(connector, native_mode);
                count = 1;
-       } else {
-               if (con->i2c_bus & VIA_I2C_BUS2) {
-                       i2c_bus = via_find_ddc_bus(0x31);
-               } else if (con->i2c_bus & VIA_I2C_BUS3) {
-                       i2c_bus = via_find_ddc_bus(0x2c);
+               goto exit;
+       }
+
+       i2c_bus_bit = VIA_I2C_BUS2;
+       for (i = 0; i < 2; i++) {
+               if (con->i2c_bus & i2c_bus_bit) {
+                       if (i2c_bus_bit & VIA_I2C_BUS2) {
+                               i2c_bus = via_find_ddc_bus(0x31);
+                       } else if (i2c_bus_bit & VIA_I2C_BUS3) {
+                               i2c_bus = via_find_ddc_bus(0x2c);
+                       } else {
+                               i2c_bus = NULL;
+                               i2c_bus_bit = i2c_bus_bit << 1;
+                               continue;
+                       }
                } else {
                        i2c_bus = NULL;
+                       i2c_bus_bit = i2c_bus_bit << 1;
+                       continue;
                }
 
-               if (i2c_bus) {
-                       edid = drm_get_edid(&con->base, i2c_bus);
-                       if (edid) {
+               edid = drm_get_edid(&con->base, i2c_bus);
+               if (edid) {
+                       if (edid->input & DRM_EDID_INPUT_DIGITAL) {
+                               
drm_mode_connector_update_edid_property(connector, edid);
                                count = drm_add_edid_modes(connector, edid);
                                kfree(edid);
-                       }
-               } else {
-                       reg_value = (vga_rcrt(VGABASE, 0x3f) & 0x0f);
-                       hdisplay = vdisplay = 0;
-                       hdisplay = via_fp_info_table[reg_value].x;
-                       vdisplay = via_fp_info_table[reg_value].y;
-
-                       if (hdisplay && vdisplay) {
-                               native_mode = drm_cvt_mode(dev, hdisplay, 
vdisplay,
-                                                       60, false, false, 
false);
-                       }
-
-                       if (native_mode) {
-                               native_mode->type = DRM_MODE_TYPE_PREFERRED | 
DRM_MODE_TYPE_DRIVER;
-                               drm_mode_set_name(native_mode);
-                               drm_mode_probed_add(connector, native_mode);
-                               count = 1;
+                               DRM_DEBUG_KMS("FP EDID information was 
obtained.\n");
+                               DRM_DEBUG_KMS("i2c_bus_bit: %x\n", i2c_bus_bit);
+                               break;
+                       } else {
+                               kfree(edid);
                        }
                }
+
+               i2c_bus_bit = i2c_bus_bit << 1;
+       }
+
+       reg_value = (vga_rcrt(VGABASE, 0x3f) & 0x0f);
+       hdisplay = vdisplay = 0;
+       hdisplay = via_fp_info_table[reg_value].x;
+       vdisplay = via_fp_info_table[reg_value].y;
+
+       if (hdisplay && vdisplay) {
+               native_mode = drm_cvt_mode(dev, hdisplay, vdisplay,
+                                       60, false, false, false);
+       }
+
+       if (native_mode) {
+               native_mode->type = DRM_MODE_TYPE_PREFERRED |
+                                               DRM_MODE_TYPE_DRIVER;
+               drm_mode_set_name(native_mode);
+               drm_mode_probed_add(connector, native_mode);
+               count = 1;
        }
 
+exit:
        DRM_DEBUG_KMS("Exiting %s.\n", __func__);
        return count;
 }
_______________________________________________
Openchrome-devel mailing list
Openchrome-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/openchrome-devel

Reply via email to