On Fri, Jan 26, 2018 at 10:39:39AM +0200, Paul Irofti wrote: > Hi, > > I have a T460 Lenovo model that, when connected to an external monitor > via a docking station, freezes the machine and produces the "snowflake" > effect on the monitor. Last time I saw this was in 2010 when working on > suspend-resume :) > > After a month of fighting to fix the issue I came up with this drm > update. The code bellow includes commits taken directly from the Linux > kernel, no local modifications. > > Notable changes are: > - improved DP link training by renegotiating with different rates and > lane values > - caching of source, sink and common rates > - max link rate limiting and related calculation changes > - switch to long and short pulse interrupts > > I have been running succesfully with this on both the affected model and > on the x250 that I used with a dozen monitors, projectors and the like > at uni. No problems so far, but would appreciate test repaorts on a > wider range of hardware. > > Comments? Mistakes? How should we proceed to get this in the tree?
For the archives, here is a diff that fixes a locking warning with the earlier patch. So you have to apply it after the former one. diff --git sys/dev/pci/drm/drm_probe_helper.c sys/dev/pci/drm/drm_probe_helper.c index 936c0c1d3a7..84a0e585d32 100644 --- sys/dev/pci/drm/drm_probe_helper.c +++ sys/dev/pci/drm/drm_probe_helper.c @@ -136,15 +136,27 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect struct drm_display_mode *mode; const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; - int count = 0; + int count = 0, ret; int mode_flags = 0; bool verbose_prune = true; enum drm_connector_status old_status; + struct drm_modeset_acquire_ctx ctx; WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); + + drm_modeset_acquire_init(&ctx, 0); + +retry: + ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx); + if (ret == -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry; + } else + WARN_ON(ret < 0); + /* set all modes to the unverified state */ list_for_each_entry(mode, &connector->modes, head) mode->status = MODE_UNVERIFIED; @@ -248,6 +260,9 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect prune: drm_mode_prune_invalid(dev, &connector->modes, verbose_prune); + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); + if (list_empty(&connector->modes)) return 0;