drm/modesetting: move some connector functions to helper.
authorDave Airlie <airlied@redhat.com>
Mon, 2 Jun 2008 01:12:28 +0000 (11:12 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 2 Jun 2008 01:12:28 +0000 (11:12 +1000)
Migrated the output mode collection into the helper.

linux-core/drm_crtc.c
linux-core/drm_crtc.h
linux-core/drm_crtc_helper.c
linux-core/drm_crtc_helper.h
linux-core/intel_crt.c
linux-core/intel_display.c
linux-core/intel_dvo.c
linux-core/intel_lvds.c
linux-core/intel_sdvo.c
linux-core/intel_tv.c

index c4210fd..74e526b 100644 (file)
@@ -286,136 +286,6 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
 EXPORT_SYMBOL(drm_crtc_cleanup);
 
 /**
- * drm_crtc_in_use - check if a given CRTC is in a mode_config
- * @crtc: CRTC to check
- *
- * LOCKING:
- * Caller must hold mode config lock.
- *
- * Walk @crtc's DRM device's mode_config and see if it's in use.
- *
- * RETURNS:
- * True if @crtc is part of the mode_config, false otherwise.
- */
-bool drm_crtc_in_use(struct drm_crtc *crtc)
-{
-       struct drm_encoder *encoder;
-       struct drm_device *dev = crtc->dev;
-       /* FIXME: Locking around list access? */
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
-               if (encoder->crtc == crtc)
-                       return true;
-       return false;
-}
-EXPORT_SYMBOL(drm_crtc_in_use);
-
-/*
- * Detailed mode info for a standard 640x480@60Hz monitor
- */
-static struct drm_display_mode std_mode[] = {
-       { DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 25200, 640, 656,
-                  752, 800, 0, 480, 490, 492, 525, 0,
-                  V_NHSYNC | V_NVSYNC) }, /* 640x480@60Hz */
-};
-
-/**
- * drm_crtc_probe_connector_modes - get complete set of display modes
- * @dev: DRM device
- * @maxX: max width for modes
- * @maxY: max height for modes
- *
- * LOCKING:
- * Caller must hold mode config lock.
- *
- * Based on @dev's mode_config layout, scan all the connectors and try to detect
- * modes on them.  Modes will first be added to the connector's probed_modes
- * list, then culled (based on validity and the @maxX, @maxY parameters) and
- * put into the normal modes list.
- *
- * Intended to be used either at bootup time or when major configuration
- * changes have occurred.
- *
- * FIXME: take into account monitor limits
- */
-void drm_crtc_probe_single_connector_modes(struct drm_connector *connector, int maxX, int maxY)
-{
-       struct drm_device *dev = connector->dev;
-       struct drm_display_mode *mode, *t;
-       int ret;
-       //if (maxX == 0 || maxY == 0) 
-       // TODO
-
-       /* set all modes to the unverified state */
-       list_for_each_entry_safe(mode, t, &connector->modes, head)
-               mode->status = MODE_UNVERIFIED;
-               
-       connector->status = (*connector->funcs->detect)(connector);
-       
-       if (connector->status == connector_status_disconnected) {
-               DRM_DEBUG("%s is disconnected\n", drm_get_connector_name(connector));
-               /* TODO set EDID to NULL */
-               return;
-       }
-       
-       ret = (*connector->funcs->get_modes)(connector);
-       
-       if (ret) {
-               drm_mode_connector_list_update(connector);
-       }
-       
-       if (maxX && maxY)
-               drm_mode_validate_size(dev, &connector->modes, maxX,
-                                      maxY, 0);
-       list_for_each_entry_safe(mode, t, &connector->modes, head) {
-               if (mode->status == MODE_OK)
-                       mode->status = (*connector->funcs->mode_valid)(connector,mode);
-       }
-       
-       
-       drm_mode_prune_invalid(dev, &connector->modes, TRUE);
-       
-       if (list_empty(&connector->modes)) {
-               struct drm_display_mode *stdmode;
-               
-               DRM_DEBUG("No valid modes on %s\n", drm_get_connector_name(connector));
-               
-               /* Should we do this here ???
-                * When no valid EDID modes are available we end up
-                * here and bailed in the past, now we add a standard
-                * 640x480@60Hz mode and carry on.
-                */
-               stdmode = drm_mode_duplicate(dev, &std_mode[0]);
-               drm_mode_probed_add(connector, stdmode);
-               drm_mode_list_concat(&connector->probed_modes,
-                                    &connector->modes);
-               
-               DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n",
-                         drm_get_connector_name(connector));
-       }
-       
-       drm_mode_sort(&connector->modes);
-       
-       DRM_DEBUG("Probed modes for %s\n", drm_get_connector_name(connector));
-       list_for_each_entry_safe(mode, t, &connector->modes, head) {
-               mode->vrefresh = drm_mode_vrefresh(mode);
-               
-               drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
-               drm_mode_debug_printmodeline(mode);
-       }
-}
-
-void drm_crtc_probe_connector_modes(struct drm_device *dev, int maxX, int maxY)
-{
-       struct drm_connector *connector;
-
-       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               drm_crtc_probe_single_connector_modes(connector, maxX, maxY);
-       }
-}
-EXPORT_SYMBOL(drm_crtc_probe_connector_modes);
-
-
-/**
  * drm_mode_probed_add - add a mode to the specified connector's probed mode list
  * @connector: connector the new mode
  * @mode: mode data
@@ -1109,7 +979,7 @@ int drm_mode_getconnector(struct drm_device *dev,
        }
 
        if (out_resp->count_modes == 0) {
-               drm_crtc_probe_single_connector_modes(connector, dev->mode_config.max_width, dev->mode_config.max_height);
+               connector->funcs->fill_modes(connector, dev->mode_config.max_width, dev->mode_config.max_height);
        }
 
        out_resp->connector_type = connector->connector_type;
index 14aa503..6dbc88a 100644 (file)
@@ -380,13 +380,10 @@ struct drm_connector_funcs {
        void (*save)(struct drm_connector *connector);
        void (*restore)(struct drm_connector *connector);
        enum drm_connector_status (*detect)(struct drm_connector *connector);
-       int (*get_modes)(struct drm_connector *connector);
+       void (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
        bool (*set_property)(struct drm_connector *connector, struct drm_property *property,
                             uint64_t val);
        void (*destroy)(struct drm_connector *connector);
-       int (*mode_valid)(struct drm_connector *connector,
-                         struct drm_display_mode *mode);
-
 };
 
 struct drm_encoder_funcs {
index 82862b5..f1a7270 100644 (file)
 #include "drm_crtc.h"
 #include "drm_crtc_helper.h"
 
+/*
+ * Detailed mode info for a standard 640x480@60Hz monitor
+ */
+static struct drm_display_mode std_mode[] = {
+       { DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 25200, 640, 656,
+                  752, 800, 0, 480, 490, 492, 525, 0,
+                  V_NHSYNC | V_NVSYNC) }, /* 640x480@60Hz */
+};
+
+/**
+ * drm_helper_probe_connector_modes - get complete set of display modes
+ * @dev: DRM device
+ * @maxX: max width for modes
+ * @maxY: max height for modes
+ *
+ * LOCKING:
+ * Caller must hold mode config lock.
+ *
+ * Based on @dev's mode_config layout, scan all the connectors and try to detect
+ * modes on them.  Modes will first be added to the connector's probed_modes
+ * list, then culled (based on validity and the @maxX, @maxY parameters) and
+ * put into the normal modes list.
+ *
+ * Intended to be used either at bootup time or when major configuration
+ * changes have occurred.
+ *
+ * FIXME: take into account monitor limits
+ */
+void drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY)
+{
+       struct drm_device *dev = connector->dev;
+       struct drm_display_mode *mode, *t;
+       struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
+       int ret;
+
+       /* set all modes to the unverified state */
+       list_for_each_entry_safe(mode, t, &connector->modes, head)
+               mode->status = MODE_UNVERIFIED;
+               
+       connector->status = (*connector->funcs->detect)(connector);
+       
+       if (connector->status == connector_status_disconnected) {
+               DRM_DEBUG("%s is disconnected\n", drm_get_connector_name(connector));
+               /* TODO set EDID to NULL */
+               return;
+       }
+       
+       ret = (*connector_funcs->get_modes)(connector);
+       
+       if (ret) {
+               drm_mode_connector_list_update(connector);
+       }
+       
+       if (maxX && maxY)
+               drm_mode_validate_size(dev, &connector->modes, maxX,
+                                      maxY, 0);
+       list_for_each_entry_safe(mode, t, &connector->modes, head) {
+               if (mode->status == MODE_OK)
+                       mode->status = (*connector_funcs->mode_valid)(connector,mode);
+       }
+       
+       
+       drm_mode_prune_invalid(dev, &connector->modes, TRUE);
+       
+       if (list_empty(&connector->modes)) {
+               struct drm_display_mode *stdmode;
+               
+               DRM_DEBUG("No valid modes on %s\n", drm_get_connector_name(connector));
+               
+               /* Should we do this here ???
+                * When no valid EDID modes are available we end up
+                * here and bailed in the past, now we add a standard
+                * 640x480@60Hz mode and carry on.
+                */
+               stdmode = drm_mode_duplicate(dev, &std_mode[0]);
+               drm_mode_probed_add(connector, stdmode);
+               drm_mode_list_concat(&connector->probed_modes,
+                                    &connector->modes);
+               
+               DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n",
+                         drm_get_connector_name(connector));
+       }
+       
+       drm_mode_sort(&connector->modes);
+       
+       DRM_DEBUG("Probed modes for %s\n", drm_get_connector_name(connector));
+       list_for_each_entry_safe(mode, t, &connector->modes, head) {
+               mode->vrefresh = drm_mode_vrefresh(mode);
+               
+               drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+               drm_mode_debug_printmodeline(mode);
+       }
+}
+EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
+
+void drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX, uint32_t maxY)
+{
+       struct drm_connector *connector;
+
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+               drm_helper_probe_single_connector_modes(connector, maxX, maxY);
+       }
+}
+EXPORT_SYMBOL(drm_helper_probe_connector_modes);
+
+
+/**
+ * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
+ * @crtc: CRTC to check
+ *
+ * LOCKING:
+ * Caller must hold mode config lock.
+ *
+ * Walk @crtc's DRM device's mode_config and see if it's in use.
+ *
+ * RETURNS:
+ * True if @crtc is part of the mode_config, false otherwise.
+ */
+bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
+{
+       struct drm_encoder *encoder;
+       struct drm_device *dev = crtc->dev;
+       /* FIXME: Locking around list access? */
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+               if (encoder->crtc == crtc)
+                       return true;
+       return false;
+}
+EXPORT_SYMBOL(drm_helper_crtc_in_use);
+
 /**
  * drm_disable_unused_functions - disable unused objects
  * @dev: DRM device
@@ -81,8 +211,8 @@ static void drm_pick_crtcs (struct drm_device *dev)
        int found;
 
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-                       connector->encoder->crtc = NULL;
-    
+               connector->encoder->crtc = NULL;
+
                /* Don't hook up connectors that are disconnected ??
                 *
                 * This is debateable. Do we want fixed /dev/fbX or
@@ -211,7 +341,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mo
 
        adjusted_mode = drm_mode_duplicate(dev, mode);
 
-       crtc->enabled = drm_crtc_in_use(crtc);
+       crtc->enabled = drm_helper_crtc_in_use(crtc);
 
        if (!crtc->enabled)
                return true;
@@ -456,7 +586,7 @@ bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
 
        mutex_lock(&dev->mode_config.mutex);
 
-       drm_crtc_probe_connector_modes(dev, 2048, 2048);
+       drm_helper_probe_connector_modes(dev, 2048, 2048);
 
        drm_pick_crtcs(dev);
 
@@ -518,7 +648,7 @@ int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_connector *c
                has_config = 1;
        }
 
-       drm_crtc_probe_connector_modes(dev, 2048, 2048);
+       drm_helper_probe_connector_modes(dev, 2048, 2048);
 
        if (!has_config)
                drm_pick_crtcs(dev);
index 063d1f7..80cb4b4 100644 (file)
@@ -55,8 +55,14 @@ struct drm_encoder_helper_funcs {
                         struct drm_display_mode *mode,
                         struct drm_display_mode *adjusted_mode);
 };
-       
 
+struct drm_connector_helper_funcs {
+       int (*get_modes)(struct drm_connector *connector);
+       int (*mode_valid)(struct drm_connector *connector,
+                         struct drm_display_mode *mode);
+};
+       
+extern void drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY);
 extern void drm_helper_disable_unused_functions(struct drm_device *dev);
 extern int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_connector *connector,
                                        bool connected);
@@ -64,7 +70,7 @@ extern bool drm_helper_initial_config(struct drm_device *dev, bool can_grow);
 extern int drm_crtc_helper_set_config(struct drm_mode_set *set);
 extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
                                     int x, int y);
-
+extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
 static inline void drm_crtc_helper_add(struct drm_crtc *crtc, const struct drm_crtc_helper_funcs *funcs)
 {
        crtc->helper_private = (void *)funcs;
@@ -75,6 +81,11 @@ static inline void drm_encoder_helper_add(struct drm_encoder *encoder, const str
        encoder->helper_private = (void *)funcs;
 }
 
+static inline void drm_connector_helper_add(struct drm_connector *connector, const struct drm_connector_helper_funcs *funcs)
+{
+       connector->helper_private = (void *)funcs;
+}
+
 
 
 #endif
index ec4c2bf..21a1e7d 100644 (file)
@@ -237,13 +237,16 @@ static const struct drm_connector_funcs intel_crt_connector_funcs = {
        .save = intel_crt_save,
        .restore = intel_crt_restore,
        .detect = intel_crt_detect,
-       .get_modes = intel_crt_get_modes,
+       .fill_modes = drm_helper_probe_single_connector_modes,
        .destroy = intel_crt_destroy,
        .set_property = intel_crt_set_property,
-       .mode_valid = intel_crt_mode_valid,
-
 };
 
+static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = {
+       .mode_valid = intel_crt_mode_valid,
+       .get_modes = intel_crt_get_modes,
+};     
+
 void intel_crt_enc_destroy(struct drm_encoder *encoder)
 {
        drm_encoder_cleanup(encoder);
@@ -283,6 +286,7 @@ void intel_crt_init(struct drm_device *dev)
        connector->doublescan_allowed = 0;
 
        drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
+       drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
 
        drm_sysfs_connector_add(connector);
 
index c1cb2bf..bbaa19d 100644 (file)
@@ -1184,7 +1184,7 @@ void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_
        if (intel_output->load_detect_temp) {
                encoder->crtc = NULL;
                intel_output->load_detect_temp = FALSE;
-               crtc->enabled = drm_crtc_in_use(crtc);
+               crtc->enabled = drm_helper_crtc_in_use(crtc);
                drm_helper_disable_unused_functions(dev);
        }
 
index 364cd65..e895d5b 100644 (file)
@@ -335,9 +335,13 @@ static const struct drm_connector_funcs intel_dvo_connector_funcs = {
        .save = intel_dvo_save,
        .restore = intel_dvo_restore,
        .detect = intel_dvo_detect,
-       .get_modes = intel_dvo_get_modes,
        .destroy = intel_dvo_destroy,
+       .fill_modes = drm_helper_probe_single_connector_modes,
+};
+
+static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = {
        .mode_valid = intel_dvo_mode_valid,
+       .get_modes = intel_dvo_get_modes,
 };
 
 void intel_dvo_enc_destroy(struct drm_encoder *encoder)
@@ -464,6 +468,7 @@ void intel_dvo_init(struct drm_device *dev)
                        break;
                }
 
+               drm_connector_helper_add(connector, &intel_dvo_connector_helper_funcs);
                connector->display_info.subpixel_order = SubPixelHorizontalRGB;
                connector->interlace_allowed = false;
                connector->doublescan_allowed = false;
index b83f392..cbe8b53 100644 (file)
@@ -342,13 +342,17 @@ static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
        .commit = intel_lvds_commit,
 };
 
+static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
+       .get_modes = intel_lvds_get_modes,
+       .mode_valid = intel_lvds_mode_valid,
+};     
+
 static const struct drm_connector_funcs intel_lvds_connector_funcs = {
        .save = intel_lvds_save,
        .restore = intel_lvds_restore,
        .detect = intel_lvds_detect,
-       .get_modes = intel_lvds_get_modes,
+       .fill_modes = drm_helper_probe_single_connector_modes,
        .destroy = intel_lvds_destroy,
-       .mode_valid = intel_lvds_mode_valid,
 };
 
 
@@ -361,6 +365,8 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
        .destroy = intel_lvds_enc_destroy,
 };
 
+
+
 /**
  * intel_lvds_init - setup LVDS connectors on this device
  * @dev: drm device
@@ -395,6 +401,7 @@ void intel_lvds_init(struct drm_device *dev)
        intel_output->type = INTEL_OUTPUT_LVDS;
 
        drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
+       drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
        connector->interlace_allowed = FALSE;
        connector->doublescan_allowed = FALSE;
index 498ad98..d3ca2a2 100644 (file)
@@ -983,11 +983,14 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
        .save = intel_sdvo_save,
        .restore = intel_sdvo_restore,
        .detect = intel_sdvo_detect,
-       .get_modes = intel_sdvo_get_modes,
+       .fill_modes = drm_helper_probe_single_connector_modes,
        .destroy = intel_sdvo_destroy,
-       .mode_valid = intel_sdvo_mode_valid,
 };
 
+static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
+       .get_modes = intel_sdvo_get_modes,
+       .mode_valid = intel_sdvo_mode_valid,
+};
 
 void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
 {
@@ -1019,7 +1022,7 @@ void intel_sdvo_init(struct drm_device *dev, int output_device)
 
        drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
                           DRM_MODE_CONNECTOR_Unknown);
-
+       drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs);
        sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
        intel_output->type = INTEL_OUTPUT_SDVO;
 
index b13b035..c3b5c09 100644 (file)
@@ -1608,11 +1608,15 @@ static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
 static const struct drm_connector_funcs intel_tv_connector_funcs = {
        .save = intel_tv_save,
        .restore = intel_tv_restore,
-       .mode_valid = intel_tv_mode_valid,
        .detect = intel_tv_detect,
-       .get_modes = intel_tv_get_modes,
        .destroy = intel_tv_destroy,
        .set_property = intel_tv_set_property,
+       .fill_modes = drm_helper_probe_single_connector_modes,
+};
+
+static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
+       .mode_valid = intel_tv_mode_valid,
+       .get_modes = intel_tv_get_modes,
 };
 
 void intel_tv_enc_destroy(struct drm_encoder *encoder)
@@ -1695,6 +1699,7 @@ intel_tv_init(struct drm_device *dev)
        tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
     
        drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs);
+       drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
        connector->interlace_allowed = FALSE;
        connector->doublescan_allowed = FALSE;