tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[PATCH] Detect monitor hotplug, used for DRM drivers (was: DDC info refresh?)



On Fri, Apr 17, 2020 at 06:21:18PM +0000, maya%NetBSD.org@localhost wrote:
> On Wed, Apr 15, 2020 at 02:23:19PM -0400, Mouse wrote:
> > It would also be enough if I could force the X server to run 1280x1024
> > whether or not it has a monitor connected.  Under 5.2, I added options
> > to the X server, one to capture DDC info to a file and one to provide a
> > file to be read to provide DDC info if none could be obtained from the
> > monitor.  This addressed the problem there.  But, under 8.0, the use of
> > 1024x768 even with a monitor connected indicates to me that it's
> > getting DDC, or moral eqvuialent, from the kernel instead of the
> > monitor, so I am inclined to doubt the same approach would work.  (I
> > can try it, certainly, but, based on the information I have now, that
> > seems like an investment of my time with a low expected return.)
> > 
> > Comments?  Thoughts?  If there is something else that this depends on
> > that I haven't mentioned, just let me know.
> 
> This feels like it'd be really hard to use.
> 
> If I was working on this, I would aim for something like this:
> - Report an event to userland upon a monitor hotplug.
> Perhaps just "monitors changed, suggesting to re-probe" is fine.
> 
> Currently, powerd/pmf look like good candidates for transmitting such
> events to userland.
> 
> - Have a small script that maps a monitor setup to a preferred
>   resolution/layout.
> 
> In your case it will be "run this one hard-coded xrandr command".
> But in the long run we could use this to have very comfortable handling
> for scenarios where people connect another monitor.

With the attached patch I can write this script (would be nice if powerd
was something X could listen to, but it only allows one listener).

cat /etc/powerd/scripts/monitor_hotplug 
#!/bin/sh

su fly -c "env DISPLAY=:0 /usr/X11R7/bin/xrandr --output DVI-0 --mode 1280x800"


And it'll actually pick the new xrandr choice on monitor hotplug.


--------------------

# HG changeset patch
# User Maya Rashish <maya%netbsd.org@localhost>
# Date 1587216560 -10800
#      Sat Apr 18 16:29:20 2020 +0300
# Branch trunk
# Node ID 18ec6488132fa5746888cc0a3de3e9ff40f315d2
# Parent  3a4ebac1a7ae7a742b0cedb6a942e3cbd85256b5
Add a powerd event for monitor hotplug.

Now if you have powerd running and have a script named
/etc/powerd/scripts/monitor_hotplug

It will be executed on monitor hotplug.

diff -r 3a4ebac1a7ae -r 18ec6488132f sys/dev/sysmon/sysmon_power.c
--- a/sys/dev/sysmon/sysmon_power.c	Thu Apr 16 15:58:13 2020 +0000
+++ b/sys/dev/sysmon/sysmon_power.c	Sat Apr 18 16:29:20 2020 +0300
@@ -130,6 +130,7 @@
 	{ PSWITCH_TYPE_ACADAPTER,	"acadapter" },
 	{ PSWITCH_TYPE_HOTKEY,		"hotkey_button" },
 	{ PSWITCH_TYPE_RADIO,		"radio_button" },
+	{ PSWITCH_TYPE_MONITOR_HOTPLUG,	"monitor_hotplug" },
 	{ -1, NULL }
 };
 
diff -r 3a4ebac1a7ae -r 18ec6488132f sys/sys/power.h
--- a/sys/sys/power.h	Thu Apr 16 15:58:13 2020 +0000
+++ b/sys/sys/power.h	Sat Apr 18 16:29:20 2020 +0300
@@ -115,7 +115,8 @@
 #define		PSWITCH_HK_VOLUME_DOWN		"volume-down"
 #define		PSWITCH_HK_VOLUME_MUTE		"volume-mute"
 #endif /* THINKPAD_NORMAL_HOTKEYS */
-#define	PSWITCH_TYPE_RADIO	6	/* radio switch */
+#define	PSWITCH_TYPE_RADIO		6	/* radio switch */
+#define	PSWITCH_TYPE_MONITOR_HOTPLUG	7	/* monitor hotplug */
 
 #define	PSWITCH_EVENT_PRESSED	0	/* button pressed, lid closed, AC off */
 #define	PSWITCH_EVENT_RELEASED	1	/* button released, lid open, AC on */
# HG changeset patch
# User Maya Rashish <maya%netbsd.org@localhost>
# Date 1587216606 -10800
#      Sat Apr 18 16:30:06 2020 +0300
# Branch trunk
# Node ID 3b62224d38ada8c0396699aaffe605e10ebc97e2
# Parent  18ec6488132fa5746888cc0a3de3e9ff40f315d2
Add monitor hotplug reporting for drm drivers.

Currently invoked by i915 and radeon.

diff -r 18ec6488132f -r 3b62224d38ad sys/external/bsd/drm2/dist/drm/drm_drv.c
--- a/sys/external/bsd/drm2/dist/drm/drm_drv.c	Sat Apr 18 16:29:20 2020 +0300
+++ b/sys/external/bsd/drm2/dist/drm/drm_drv.c	Sat Apr 18 16:30:06 2020 +0300
@@ -660,6 +660,16 @@
 	kref_init(&dev->ref);
 	dev->dev = parent;
 	dev->driver = driver;
+#ifdef __NetBSD__
+	dev->sc_monitor_hotplug.smpsw_name = device_xname(dev->dev);
+	dev->sc_monitor_hotplug.smpsw_type = PSWITCH_TYPE_MONITOR_HOTPLUG;
+
+	ret = sysmon_pswitch_register(&dev->sc_monitor_hotplug);
+	if (ret) {
+		kfree(dev);
+		return NULL;
+	}
+#endif
 
 	INIT_LIST_HEAD(&dev->filelist);
 	INIT_LIST_HEAD(&dev->ctxlist);
@@ -727,6 +737,9 @@
 	mutex_destroy(&dev->master_mutex);
 	mutex_destroy(&dev->ctxlist_mutex);
 	mutex_destroy(&dev->struct_mutex);
+#ifdef __NetBSD__
+	sysmon_pswitch_unregister(&dev->sc_monitor_hotplug);
+#endif
 	kfree(dev);
 	return NULL;
 }
@@ -739,6 +752,10 @@
 	if (drm_core_check_feature(dev, DRIVER_GEM))
 		drm_gem_destroy(dev);
 
+#ifdef __NetBSD__
+	sysmon_pswitch_unregister(&dev->sc_monitor_hotplug);
+#endif
+
 	drm_legacy_ctxbitmap_cleanup(dev);
 	drm_ht_remove(&dev->map_hash);
 	drm_fs_inode_free(dev->anon_inode);
diff -r 18ec6488132f -r 3b62224d38ad sys/external/bsd/drm2/dist/drm/drm_probe_helper.c
--- a/sys/external/bsd/drm2/dist/drm/drm_probe_helper.c	Sat Apr 18 16:29:20 2020 +0300
+++ b/sys/external/bsd/drm2/dist/drm/drm_probe_helper.c	Sat Apr 18 16:30:06 2020 +0300
@@ -328,6 +330,9 @@
  */
 void drm_kms_helper_hotplug_event(struct drm_device *dev)
 {
+#ifdef __NetBSD__
+	sysmon_pswitch_event(&dev->sc_monitor_hotplug, PSWITCH_EVENT_PRESSED);
+#endif
 	/* send a uevent + call fbdev */
 	drm_sysfs_hotplug_event(dev);
 	if (dev->mode_config.funcs->output_poll_changed)
diff -r 18ec6488132f -r 3b62224d38ad sys/external/bsd/drm2/dist/include/drm/drmP.h
--- a/sys/external/bsd/drm2/dist/include/drm/drmP.h	Sat Apr 18 16:29:20 2020 +0300
+++ b/sys/external/bsd/drm2/dist/include/drm/drmP.h	Sat Apr 18 16:30:06 2020 +0300
@@ -903,6 +903,7 @@
 	int irq;
 #ifdef __NetBSD__
 	struct drm_bus_irq_cookie *irq_cookie;
+	struct sysmon_pswitch sc_monitor_hotplug;
 #endif
 
 	/*



Home | Main Index | Thread Index | Old Index