diff options
Diffstat (limited to 'linux-core/drm_crtc_helper.c')
-rw-r--r-- | linux-core/drm_crtc_helper.c | 123 |
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) { |