Hi, Recently I took over the old iMac11,2 of my son, and what else to do with it other than installing OpenBSD and see what happens. The first thing which happened after the installation was that the screen remained dark after the radeondrm(4) KMS initialization.
After some painful debugging, and exchanging forth and back with jsg@, I've noticed that when enabling DRMDEBUG, radeondrm(4) just works fine! Smells like a timing issue. After doing some more investigations I've figured out that when removing a specific debug printf in drm_dp_helper.c, just before an usleep_range() statement, it fails again: case DP_AUX_NATIVE_REPLY_DEFER: -> DRM_DEBUG_KMS("native defer\n"); /* * We could check for I2C bit rate capabilities and if * available adjust this interval. We could also be * more careful with DP-to-legacy adapters where a * long legacy cable may force very low I2C bit rates. * * For now just defer for long enough to hopefully be * safe for all use-cases. */ usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 100); continue; This usleep_range() expands to usleep_range(500, 600), and we wrap it in this function on OpenBSD: static inline void usleep_range(unsigned long min, unsigned long max) { DELAY(min); } In my case the 500us was too short, while the 600us works fine. Based on that jsg@ told me that there is an discussion on-going to change usleep_range() to calculate (min + max) / 2, which would change this specific usleep_range() line to 550us, which is enough in my case to make radeondrm(4) work fine on my iMac. We would like to understand if this diff has any negative impact on other devices. Can you please give it a spin therefore? Index: dev/pci/drm/include/linux/delay.h =================================================================== RCS file: /cvs/src/sys/dev/pci/drm/include/linux/delay.h,v retrieving revision 1.2 diff -u -p -u -p -r1.2 delay.h --- dev/pci/drm/include/linux/delay.h 8 Jun 2020 04:48:14 -0000 1.2 +++ dev/pci/drm/include/linux/delay.h 14 Aug 2020 11:44:43 -0000 @@ -20,7 +20,7 @@ ndelay(unsigned long nsecs) static inline void usleep_range(unsigned long min, unsigned long max) { - DELAY(min); + DELAY((min + max) / 2); } static inline void