drm/radeon: restructure edid fetching
authorAlex Deucher <alexander.deucher@amd.com>
Tue, 15 Jul 2014 14:38:10 +0000 (10:38 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 5 Aug 2014 12:53:29 +0000 (08:53 -0400)
Split radeon_ddc_get_modes() and move it into
radeon_connectors.c since that is the only place
that uses it.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_mode.h

index ce50ea6..5b5d28a 100644 (file)
@@ -262,6 +262,79 @@ static struct drm_encoder *radeon_find_encoder(struct drm_connector *connector,
        return NULL;
 }
 
+static void radeon_connector_get_edid(struct drm_connector *connector)
+{
+       struct drm_device *dev = connector->dev;
+       struct radeon_device *rdev = dev->dev_private;
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+       if (radeon_connector->edid)
+               return;
+
+       /* on hw with routers, select right port */
+       if (radeon_connector->router.ddc_valid)
+               radeon_router_select_ddc_port(radeon_connector);
+
+       if ((radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
+            ENCODER_OBJECT_ID_NONE) &&
+           radeon_connector->ddc_bus->has_aux) {
+               radeon_connector->edid = drm_get_edid(connector,
+                                                     &radeon_connector->ddc_bus->aux.ddc);
+       } else if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
+                  (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
+               struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
+
+               if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
+                    dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&
+                   radeon_connector->ddc_bus->has_aux)
+                       radeon_connector->edid = drm_get_edid(&radeon_connector->base,
+                                                             &radeon_connector->ddc_bus->aux.ddc);
+               else if (radeon_connector->ddc_bus)
+                       radeon_connector->edid = drm_get_edid(&radeon_connector->base,
+                                                             &radeon_connector->ddc_bus->adapter);
+       } else if (radeon_connector->ddc_bus) {
+               radeon_connector->edid = drm_get_edid(&radeon_connector->base,
+                                                     &radeon_connector->ddc_bus->adapter);
+       }
+
+       if (!radeon_connector->edid) {
+               if (rdev->is_atom_bios) {
+                       /* some laptops provide a hardcoded edid in rom for LCDs */
+                       if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) ||
+                            (connector->connector_type == DRM_MODE_CONNECTOR_eDP)))
+                               radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
+               } else {
+                       /* some servers provide a hardcoded edid in rom for KVMs */
+                       radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
+               }
+       }
+}
+
+static void radeon_connector_free_edid(struct drm_connector *connector)
+{
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+       if (radeon_connector->edid) {
+               kfree(radeon_connector->edid);
+               radeon_connector->edid = NULL;
+       }
+}
+
+static int radeon_ddc_get_modes(struct drm_connector *connector)
+{
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+       int ret;
+
+       if (radeon_connector->edid) {
+               drm_mode_connector_update_edid_property(connector, radeon_connector->edid);
+               ret = drm_add_edid_modes(connector, radeon_connector->edid);
+               drm_edid_to_eld(connector, radeon_connector->edid);
+               return ret;
+       }
+       drm_mode_connector_update_edid_property(connector, NULL);
+       return 0;
+}
+
 static struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
 {
        int enc_id = connector->encoder_ids[0];
@@ -661,22 +734,20 @@ static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
 
 static int radeon_lvds_get_modes(struct drm_connector *connector)
 {
-       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
        struct drm_encoder *encoder;
        int ret = 0;
        struct drm_display_mode *mode;
 
-       if (radeon_connector->ddc_bus) {
-               ret = radeon_ddc_get_modes(radeon_connector);
-               if (ret > 0) {
-                       encoder = radeon_best_single_encoder(connector);
-                       if (encoder) {
-                               radeon_fixup_lvds_native_mode(encoder, connector);
-                               /* add scaled modes */
-                               radeon_add_common_modes(encoder, connector);
-                       }
-                       return ret;
+       radeon_connector_get_edid(connector);
+       ret = radeon_ddc_get_modes(connector);
+       if (ret > 0) {
+               encoder = radeon_best_single_encoder(connector);
+               if (encoder) {
+                       radeon_fixup_lvds_native_mode(encoder, connector);
+                       /* add scaled modes */
+                       radeon_add_common_modes(encoder, connector);
                }
+               return ret;
        }
 
        encoder = radeon_best_single_encoder(connector);
@@ -751,16 +822,9 @@ radeon_lvds_detect(struct drm_connector *connector, bool force)
        }
 
        /* check for edid as well */
+       radeon_connector_get_edid(connector);
        if (radeon_connector->edid)
                ret = connector_status_connected;
-       else {
-               if (radeon_connector->ddc_bus) {
-                       radeon_connector->edid = drm_get_edid(&radeon_connector->base,
-                                                             &radeon_connector->ddc_bus->adapter);
-                       if (radeon_connector->edid)
-                               ret = connector_status_connected;
-               }
-       }
        /* check acpi lid status ??? */
 
        radeon_connector_update_scratch_regs(connector, ret);
@@ -773,8 +837,7 @@ static void radeon_connector_destroy(struct drm_connector *connector)
 {
        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 
-       if (radeon_connector->edid)
-               kfree(radeon_connector->edid);
+       radeon_connector_free_edid(connector);
        kfree(radeon_connector->con_priv);
        drm_connector_unregister(connector);
        drm_connector_cleanup(connector);
@@ -833,10 +896,10 @@ static const struct drm_connector_funcs radeon_lvds_connector_funcs = {
 
 static int radeon_vga_get_modes(struct drm_connector *connector)
 {
-       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
        int ret;
 
-       ret = radeon_ddc_get_modes(radeon_connector);
+       radeon_connector_get_edid(connector);
+       ret = radeon_ddc_get_modes(connector);
 
        radeon_get_native_mode(connector);
 
@@ -881,28 +944,26 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
                dret = radeon_ddc_probe(radeon_connector, false);
        if (dret) {
                radeon_connector->detected_by_load = false;
-               if (radeon_connector->edid) {
-                       kfree(radeon_connector->edid);
-                       radeon_connector->edid = NULL;
-               }
-               radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
+               radeon_connector_free_edid(connector);
+               radeon_connector_get_edid(connector);
 
                if (!radeon_connector->edid) {
                        DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
                                        connector->name);
                        ret = connector_status_connected;
                } else {
-                       radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
+                       radeon_connector->use_digital =
+                               !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
 
                        /* some oems have boards with separate digital and analog connectors
                         * with a shared ddc line (often vga + hdmi)
                         */
                        if (radeon_connector->use_digital && radeon_connector->shared_ddc) {
-                               kfree(radeon_connector->edid);
-                               radeon_connector->edid = NULL;
+                               radeon_connector_free_edid(connector);
                                ret = connector_status_disconnected;
-                       } else
+                       } else {
                                ret = connector_status_connected;
+                       }
                }
        } else {
 
@@ -1094,18 +1155,16 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
                dret = radeon_ddc_probe(radeon_connector, false);
        if (dret) {
                radeon_connector->detected_by_load = false;
-               if (radeon_connector->edid) {
-                       kfree(radeon_connector->edid);
-                       radeon_connector->edid = NULL;
-               }
-               radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
+               radeon_connector_free_edid(connector);
+               radeon_connector_get_edid(connector);
 
                if (!radeon_connector->edid) {
                        DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
                                        connector->name);
                        /* rs690 seems to have a problem with connectors not existing and always
                         * return a block of 0's. If we see this just stop polling on this output */
-                       if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) && radeon_connector->base.null_edid_counter) {
+                       if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) &&
+                           radeon_connector->base.null_edid_counter) {
                                ret = connector_status_disconnected;
                                DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n",
                                          connector->name);
@@ -1115,18 +1174,18 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
                                broken_edid = true; /* defer use_digital to later */
                        }
                } else {
-                       radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
+                       radeon_connector->use_digital =
+                               !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
 
                        /* some oems have boards with separate digital and analog connectors
                         * with a shared ddc line (often vga + hdmi)
                         */
                        if ((!radeon_connector->use_digital) && radeon_connector->shared_ddc) {
-                               kfree(radeon_connector->edid);
-                               radeon_connector->edid = NULL;
+                               radeon_connector_free_edid(connector);
                                ret = connector_status_disconnected;
-                       } else
+                       } else {
                                ret = connector_status_connected;
-
+                       }
                        /* This gets complicated.  We have boards with VGA + HDMI with a
                         * shared DDC line and we have boards with DVI-D + HDMI with a shared
                         * DDC line.  The latter is more complex because with DVI<->HDMI adapters
@@ -1146,8 +1205,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
                                                if (list_connector->connector_type != DRM_MODE_CONNECTOR_VGA) {
                                                        /* hpd is our only option in this case */
                                                        if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
-                                                               kfree(radeon_connector->edid);
-                                                               radeon_connector->edid = NULL;
+                                                               radeon_connector_free_edid(connector);
                                                                ret = connector_status_disconnected;
                                                        }
                                                }
@@ -1356,7 +1414,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
                        if (!radeon_dig_connector->edp_on)
                                atombios_set_edp_panel_power(connector,
                                                             ATOM_TRANSMITTER_ACTION_POWER_ON);
-                       ret = radeon_ddc_get_modes(radeon_connector);
+                       radeon_connector_get_edid(connector);
+                       ret = radeon_ddc_get_modes(connector);
                        if (!radeon_dig_connector->edp_on)
                                atombios_set_edp_panel_power(connector,
                                                             ATOM_TRANSMITTER_ACTION_POWER_OFF);
@@ -1367,7 +1426,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
                                if (encoder)
                                        radeon_atom_ext_encoder_setup_ddc(encoder);
                        }
-                       ret = radeon_ddc_get_modes(radeon_connector);
+                       radeon_connector_get_edid(connector);
+                       ret = radeon_ddc_get_modes(connector);
                }
 
                if (ret > 0) {
@@ -1400,7 +1460,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
                        if (encoder)
                                radeon_atom_ext_encoder_setup_ddc(encoder);
                }
-               ret = radeon_ddc_get_modes(radeon_connector);
+               radeon_connector_get_edid(connector);
+               ret = radeon_ddc_get_modes(connector);
 
                radeon_get_native_mode(connector);
        }
@@ -1493,10 +1554,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
                goto out;
        }
 
-       if (radeon_connector->edid) {
-               kfree(radeon_connector->edid);
-               radeon_connector->edid = NULL;
-       }
+       radeon_connector_free_edid(connector);
 
        if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
            (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
index bf25061..004f30c 100644 (file)
@@ -823,64 +823,6 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
        return ret;
 }
 
-int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
-{
-       struct drm_device *dev = radeon_connector->base.dev;
-       struct radeon_device *rdev = dev->dev_private;
-       int ret = 0;
-
-       /* don't leak the edid if we already fetched it in detect() */
-       if (radeon_connector->edid)
-               goto got_edid;
-
-       /* on hw with routers, select right port */
-       if (radeon_connector->router.ddc_valid)
-               radeon_router_select_ddc_port(radeon_connector);
-
-       if (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) !=
-           ENCODER_OBJECT_ID_NONE) {
-               if (radeon_connector->ddc_bus->has_aux)
-                       radeon_connector->edid = drm_get_edid(&radeon_connector->base,
-                                                             &radeon_connector->ddc_bus->aux.ddc);
-       } else if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
-                  (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) {
-               struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
-
-               if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||
-                    dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&
-                   radeon_connector->ddc_bus->has_aux)
-                       radeon_connector->edid = drm_get_edid(&radeon_connector->base,
-                                                             &radeon_connector->ddc_bus->aux.ddc);
-               else if (radeon_connector->ddc_bus && !radeon_connector->edid)
-                       radeon_connector->edid = drm_get_edid(&radeon_connector->base,
-                                                             &radeon_connector->ddc_bus->adapter);
-       } else {
-               if (radeon_connector->ddc_bus && !radeon_connector->edid)
-                       radeon_connector->edid = drm_get_edid(&radeon_connector->base,
-                                                             &radeon_connector->ddc_bus->adapter);
-       }
-
-       if (!radeon_connector->edid) {
-               if (rdev->is_atom_bios) {
-                       /* some laptops provide a hardcoded edid in rom for LCDs */
-                       if (((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_LVDS) ||
-                            (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)))
-                               radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
-               } else
-                       /* some servers provide a hardcoded edid in rom for KVMs */
-                       radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev);
-       }
-       if (radeon_connector->edid) {
-got_edid:
-               drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid);
-               ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid);
-               drm_edid_to_eld(&radeon_connector->base, radeon_connector->edid);
-               return ret;
-       }
-       drm_mode_connector_update_edid_property(&radeon_connector->base, NULL);
-       return 0;
-}
-
 /* avivo */
 
 /**
index 0592ddb..9c2bfcd 100644 (file)
@@ -738,7 +738,6 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c,
 extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector);
 extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector);
 extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux);
-extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
 
 extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector);