summaryrefslogtreecommitdiff
path: root/linux-core/drm_crtc_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-core/drm_crtc_helper.c')
-rw-r--r--linux-core/drm_crtc_helper.c123
1 files changed, 34 insertions, 89 deletions
diff --git a/linux-core/drm_crtc_helper.c b/linux-core/drm_crtc_helper.c
index 4083d6b7..777820d7 100644
--- a/linux-core/drm_crtc_helper.c
+++ b/linux-core/drm_crtc_helper.c
@@ -67,6 +67,7 @@ void drm_helper_probe_single_connector_modes(struct drm_connector *connector, ui
struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
int ret;
+ DRM_DEBUG("%s\n", drm_get_connector_name(connector));
/* set all modes to the unverified state */
list_for_each_entry_safe(mode, t, &connector->modes, head)
mode->status = MODE_UNVERIFIED;
@@ -186,8 +187,11 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
- if (!crtc->enabled)
+ crtc->enabled = drm_helper_crtc_in_use(crtc);
+ if (!crtc->enabled) {
crtc_funcs->dpms(crtc, DPMSModeOff);
+ crtc->fb = NULL;
+ }
}
}
EXPORT_SYMBOL(drm_helper_disable_unused_functions);
@@ -209,6 +213,7 @@ static void drm_pick_crtcs (struct drm_device *dev)
struct drm_connector_helper_funcs *connector_funcs;
int found;
+ DRM_DEBUG("\n");
/* clean out all the encoder/crtc combos */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
encoder->crtc = NULL;
@@ -496,6 +501,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
crtc_funcs = set->crtc->helper_private;
DRM_DEBUG("crtc: %p fb: %p connectors: %p num_connectors: %i (x, y) (%i, %i)\n", set->crtc, set->fb, set->connectors, set->num_connectors, set->x, set->y);
+
dev = set->crtc->dev;
/* save previous config */
@@ -514,8 +520,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
/* We should be able to check here if the fb has the same properties
* and then just flip_or_move it */
- if (set->crtc->fb != set->fb)
- flip_or_move = true;
+ if (set->crtc->fb != set->fb) {
+ /* if we have no fb then its a change not a flip */
+ if (set->crtc->fb == NULL)
+ changed = true;
+ else
+ flip_or_move = true;
+ }
if (set->x != set->crtc->x || set->y != set->crtc->y)
flip_or_move = true;
@@ -532,7 +543,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
save_encoders[count++] = connector->encoder;
- new_encoder = NULL;
+ new_encoder = connector->encoder;
for (ro = 0; ro < set->num_connectors; ro++) {
if (set->connectors[ro] == connector) {
new_encoder = connector_funcs->best_encoder(connector);
@@ -626,6 +637,22 @@ fail_no_encoder:
}
EXPORT_SYMBOL(drm_crtc_helper_set_config);
+bool drm_helper_plugged_event(struct drm_device *dev)
+{
+ DRM_DEBUG("\n");
+
+ drm_helper_probe_connector_modes(dev, dev->mode_config.max_width, dev->mode_config.max_height);
+
+ drm_pick_crtcs(dev);
+
+ /* alert the driver fb layer */
+ dev->mode_config.funcs->fb_changed(dev);
+
+ drm_helper_disable_unused_functions(dev);
+
+ drm_sysfs_hotplug_event(dev);
+ return true;
+}
/**
* drm_initial_config - setup a sane initial connector configuration
* @dev: DRM device
@@ -643,45 +670,9 @@ EXPORT_SYMBOL(drm_crtc_helper_set_config);
*/
bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
{
- struct drm_connector *connector;
int ret = false;
- mutex_lock(&dev->mode_config.mutex);
-
- drm_helper_probe_connector_modes(dev, 2048, 2048);
-
- drm_pick_crtcs(dev);
-
- /* This is a little screwy, as we've already walked the connectors
- * above, but it's a little bit of magic too. There's the potential
- * for things not to get setup above if an existing device gets
- * re-assigned thus confusing the hardware. By walking the connectors
- * this fixes up their crtc's.
- */
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-
- struct drm_encoder *encoder = connector->encoder;
- struct drm_crtc *crtc;
-
- if (!encoder)
- continue;
-
- crtc = connector->encoder->crtc;
-
- /* can't setup the connector if there's no assigned mode */
- if (!crtc || !crtc->desired_mode)
- continue;
-
- dev->driver->fb_probe(dev, crtc, connector);
-
- /* and needs an attached fb */
- if (crtc->fb)
- drm_crtc_helper_set_mode(crtc, crtc->desired_mode, 0, 0);
- }
-
- drm_helper_disable_unused_functions(dev);
-
- mutex_unlock(&dev->mode_config.mutex);
+ drm_helper_plugged_event(dev);
return ret;
}
EXPORT_SYMBOL(drm_helper_initial_config);
@@ -699,62 +690,16 @@ EXPORT_SYMBOL(drm_helper_initial_config);
* RETURNS:
* Zero on success, errno on failure.
*/
-int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_connector *connector,
- bool connected)
+int drm_helper_hotplug_stage_two(struct drm_device *dev)
{
- int has_config = 0;
-
dev->mode_config.hotplug_counter++;
- /* We might want to do something more here */
- if (!connected) {
- DRM_DEBUG("not connected\n");
- return 0;
- }
-
- if (connector->encoder) {
- if (connector->encoder->crtc && connector->encoder->crtc->desired_mode) {
- DRM_DEBUG("drm thinks that the connector already has a config\n");
- has_config = 1;
- }
- }
-
- drm_helper_probe_connector_modes(dev, 2048, 2048);
-
- if (!has_config)
- drm_pick_crtcs(dev);
-
- if (!connector->encoder) {
- DRM_DEBUG("could not find a desired mode or crtc for connector\n");
- return 1;
- }
-
- if (!connector->encoder->crtc || !connector->encoder->crtc->desired_mode) {
- DRM_DEBUG("could not find a desired mode or crtc for connector\n");
- return 1;
- }
-
- /* We should really check if there is a fb using this crtc */
- if (!has_config)
- dev->driver->fb_probe(dev, connector->encoder->crtc, connector);
- else {
- dev->driver->fb_resize(dev, connector->encoder->crtc);
-
-#if 0
- if (!drm_crtc_set_mode(connector->encoder->crtc, connector->encoder->crtc->desired_mode, 0, 0))
- DRM_ERROR("failed to set mode after hotplug\n");
-#endif
- }
-
- drm_sysfs_hotplug_event(dev);
-
- drm_helper_disable_unused_functions(dev);
+ drm_helper_plugged_event(dev);
return 0;
}
EXPORT_SYMBOL(drm_helper_hotplug_stage_two);
-
int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
struct drm_mode_fb_cmd *mode_cmd)
{