blank = true;
}
- if (!set->connectors && modeset) {
+ if (!set->connectors && (modeset || switch_fb)) {
DRM_ERROR("Sanity check failed\n");
goto out;
}
* Wiring up the encoders and connectors.
*/
- if (modeset) {
+ /* for switch_fb we verify if any important changes happened */
+ if (modeset || switch_fb) {
/* Mode validation */
hw_mode = nv50_kms_to_hw_mode(set->mode);
DRM_ERROR("Mode not ok\n");
goto out;
}
- }
- /* Validation done, move on to cleaning of existing structures. */
+ /* verify if any "sneaky" changes happened */
+ if (output != connector->output)
+ modeset = true;
+
+ if (output->crtc != crtc)
+ modeset = true;
+ }
+ }
+ /* Validation done, move on to cleaning of existing structures. */
+ if (modeset) {
/* find encoders that use this crtc. */
list_for_each_entry(drm_encoder, &dev->mode_config.encoder_list, head) {
if (drm_encoder->crtc == set->crtc) {
if (blank) {
crtc = to_nv50_crtc(set->crtc);
- /* keeping the encoders and connectors attached, so they can be tracked */
set->crtc->enabled = false;
+
+ /* disconnect encoders and connectors */
+ for (i = 0; i < set->num_connectors; i++) {
+ drm_connector = set->connectors[i];
+
+ if (!drm_connector->encoder)
+ continue;
+
+ drm_connector->encoder->crtc = NULL;
+ drm_connector->encoder = NULL;
+ }
}
/**
goto out;
}
- /* detach any outputs that are currently running on this crtc */
+ /* detach any outputs that are currently unused */
list_for_each_entry(drm_encoder, &dev->mode_config.encoder_list, head) {
- if (drm_encoder->crtc == set->crtc) {
+ if (!drm_encoder->crtc) {
output = to_nv50_output(drm_encoder);
rval = output->execute_mode(output, true);
if (switch_fb && !modeset && !blank) {
crtc = to_nv50_crtc(set->crtc);
- rval = crtc->blank(crtc, true);
- if (rval != 0) {
- DRM_ERROR("blanking failed\n");
- goto out;
- }
-
rval = crtc->set_fb(crtc);
if (rval != 0) {
DRM_ERROR("set_fb failed\n");
/* next line changes crtc, so putting it here is important */
display->last_crtc = crtc->index;
+ }
+ if (switch_fb || modeset) {
/* this is executed immediately */
list_for_each_entry(output, &display->outputs, item) {
if (output->crtc != crtc)
display->update(display);
+ /* Update the current mode, now that all has gone well. */
+ if (modeset) {
+ set->crtc->mode = *(set->mode);
+ set->crtc->x = set->x;
+ set->crtc->y = set->y;
+ }
+
kfree(hw_mode);
return 0;
uint64_t prop_val;
rval = drm_connector_property_get_value(drm_connector, dev->mode_config.dvi_i_select_subconnector_property, &prop_val);
- if (!rval) {
+ if (rval) {
DRM_ERROR("Unable to find select subconnector property, defaulting to DVI-D\n");
return true;
}
}
rval = drm_connector_property_get_value(drm_connector, dev->mode_config.dvi_i_subconnector_property, &prop_val);
- if (!rval) {
+ if (rval) {
DRM_ERROR("Unable to find subconnector property, defaulting to DVI-D\n");
return true;
}