Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dell UltraSharp 2209WAf: DDC communication failed #424

Open
w8jcik opened this issue May 28, 2024 · 8 comments
Open

Dell UltraSharp 2209WAf: DDC communication failed #424

w8jcik opened this issue May 28, 2024 · 8 comments
Labels
monitor specific problems with particular monitors

Comments

@w8jcik
Copy link

w8jcik commented May 28, 2024

I have three displays connected directly to an Intel GPU.

Two displays work fine with ddcutil but the third Dell 2209WAf shows DDC communication failed.

Failing Dell 2209WAf is capable of DDC (display, wires), based on a fact that it's DDC works after reboot to Windows.

Debug commands

Output from ddcutil interrogate --verbose
DELL-2209WAf-interrogate-report.log
(intentionally disconnected other displays for the report).

Looking at some past issues I also tried calling

ddcutil detect --ddc  # no extra output
ddcutil detect --f4  # all strategies failed
ddcutil detect --maxtries 15,15,15 --sleep-multiplier=2 --stats   # no change from ddcutil detect --stats
# tried different multipliers 1.1, 1.2, 1.3, 1.4, 1.5, 2, 5, 10 ... 99

Display does not get a number, so calling by a bus number

ddcutil --bus 3 setvcp 10 50 --noverify
DDC communication failed for monitor on bus /dev/i2c-3

GPU

inxi -G
Graphics:
  Device-1: Intel Iris Pro Graphics 580 driver: i915 v: kernel
  Display: wayland server: X.Org v: 23.2.6 with: Xwayland v: 23.2.6
    compositor: gnome-shell v: 46.0 driver: X: loaded: modesetting
    unloaded: fbdev,vesa dri: iris gpu: i915 resolution: 2560x1440~60Hz
  API: EGL v: 1.5 drivers: iris,swrast
    platforms: wayland,x11,surfaceless,device
  API: OpenGL v: 4.6 compat-v: 4.5 vendor: intel mesa v: 24.0.5-1ubuntu1
    renderer: Mesa Intel Iris Pro Graphics 580 (SKL GT4)
  API: Vulkan v: 1.3.275 drivers: N/A surfaces: xcb,xlib,wayland

i2c-dev is built into kernel, the default Ubuntu 24.04 LTS kernel.

Versions of ddcutil

I tried [email protected] shipped with Ubuntu 24.04 LTS, as well as manually built 1.4.5 and 2.1.5-dev.

Other platforms

Brightness control of all three displays works in Windows, so it is not related to wires or wrong settings of the display. The application I tried is called https://github.com/emoacht/Monitorian. Although I think that Monitorian does nothing special, just Windows API does DDC out of the box.

Past issues

I found this issue https://unix.stackexchange.com/questions/546000/adjust-backlight-via-ddc

I am the developer of ddcutil.

It looks like you have a monitor with a marginal I2C implementation. The Nvidia options are forcing the driver to use the lowest bus speed defined in the I2C spec, 100 kbps. Unfortunately, there's no way to tell the driver to use an even lower bus speed.

The OP solved it by passing parameters to Nvidia kernel module, but this is an Intel GPU.

@rockowitz rockowitz added the monitor specific problems with particular monitors label Jun 17, 2024
@rockowitz
Copy link
Owner

Commonly, DDC communication failures entail data corruption, i.e. malformed packets. Such errors are sometimes correctable by increasing the time between packet writes and reads (i.e. with option --sleep-multiplier). In this case, the error code returned when writing DDC requests to the monitor is ENXIO.

From the i2c-dev documentation:

ENXIO

Returned by I2C adapters to indicate that the address phase of a transfer didn’t get an ACK. 
While it might just mean an I2C device was temporarily not responding, usually it means 
there’s nothing listening at that address.

For /dev/i2c-1 and /dev/i2c-2, this status really means that there's nothing listening at address x37. For /dev/i2c-3, we know there is something listening, but the monitor fails to properly communicate.

This is a very old monitor. Sometimes the Windows video drivers can better handle a monitor having a marginal DDC/CI implementation, than do Linux drivers. Perhaps ddcci (package ddcci-dkms) will have better luck since it is implemented as driiver, but I'm afraid you're out of luck trying to use ddcutil.

@w8jcik
Copy link
Author

w8jcik commented Jun 18, 2024

but I'm afraid you're out of luck trying to use ddcutil.

Thank you a lot for looking into the details. Despite that it seems to be a lost cause.
Does it mean that the issue is mostly in i2c-dev and some related implementation of the Intel GPU driver?

This is a very old monitor.

I know the display is very old, but newer displays also have issues. It is possible that I have some soft spot regarding UltraSharp displays from Dell.

I tried ddcci-dkms as you suggested. It took me a while to set it up, but I finally made it work with

echo 'ddcci 0x37' | sudo tee /sys/bus/i2c/devices/i2c-3/new_device

It produces following response

[  817.062522] ddcci: initializing ddcci driver
[  817.062593] ddcci: ddcci driver initialized
[ 1889.858749] ddcci 3-0037: probing core device [6e]
[ 1889.859860] ddcci 3-0037: [6e:6e] writing identification command in block mode: -6
[ 1889.859880] ddcci 3-0037: DDC/CI bus quirk detected: writes must be done bytewise
[ 1889.925009] ddcci 3-0037: [6e:6e] writing identification command in bytewise mode: 0
[ 1889.999678] ddcci 3-0037: [6e:6e] identification response: 6e 80 f1
[ 1889.999694] ddcci 3-0037: [6e:6e] invalid DDC/CI response, corrupted data - xor is 0x4f, length 0x00
[ 1889.999708] ddcci ddcci3: DDC/CI main device sent broken response on identification. Trying to detect solely based on capability information.
[ 1889.999714] ddcci: sending to 3:6e:6e: f3 00 00
[ 1890.000836] ddcci 3-0037: [6e:6e] got neither valid identification nor capability data
[ 1890.000859] ddcci 3-0037: core device [6e] probe failed: -19
[ 1890.000896] i2c i2c-3: new_device: Instantiated device ddcci at 0x37

I was also running following command multiple times while playing with the display menu

ddcutil --bus 3 setvcp 10 0 --noverify --skip-ddc-checks --sleep-multiplier 2 --disable-dynamic-sleep --maxtries "15,15,15"

Very very rarely, maybe once per 100 attempts it actually changes the brightness. Although requested 0% becomes something like 81%.

It is doable only for 0%.

The usual response is

$ ddcutil --bus 3 setvcp 10 0 --skip-ddc-checks --sleep-multiplier 2 --disable-dynamic-sleep --maxtries "15,15,15"
VCP (aka MCCS) version for display is undetected or less than 2.0. Interpretation may not be accurate.
Setting value failed for feature x10, rc=DDCRC_RETRIES(-3007): maximum retries exceeded
    Try errors: DDCRC_RETRIES

This is a very old monitor. Sometimes the Windows video drivers can better handle a monitor having a marginal DDC/CI implementation, than do Linux drivers.

How do you think, if I manage to record I2C traffic with logic analyzer (to compare between Windows and Linux), would this shed some light on the problem? Or will it be still difficult to analyze?

The second question is: Aren't there any kernel module parameters that affect I2C with Intel GPUs? I only see switches related to NVidia in the documentation.

@w8jcik w8jcik closed this as completed Jun 18, 2024
@w8jcik w8jcik reopened this Jun 19, 2024
@w8jcik
Copy link
Author

w8jcik commented Jun 19, 2024

I didn't close this intentionally. I must have pressed close by accident on the phone.
Sorry for that, not using GitHub very often.

@rockowitz
Copy link
Owner

The issue is layers below i2c-dev, i.e. the video driver. i2c-dev "just" provides a common, standard kernel interface for all i2c drivers. However, there is one quirk that you might be able to exploit. i2c-dev provides two interfaces, one using ioctl() and a more user friendly interface using read() and write(). In principle these should be the same, but it turns out they call different functions in the video driver. If the proprietary nvidia driver is built in an unusual one path through i2c-dev fails. I rather doubt that this has any relevance for you, but you could try using option --use-file-io.

Are saying that you can use ddcci to change monitor brightness by writing to a /dev/bus/ddcci or just that , or just that were able to get it to install?

The error message in your setvcp example apparently has a bug. The "Try errors" line should list the individual errors from each retry. Option --excp is one way to see the individual errors. However, I doubt this will tell us anything we don't already know.

The output from a logic analyser might be of interest in a bug report to the driver developers. From my perspective, the value of line sniffing lies in reverse engineering the protocols used by the manufacturers' Windows applications to control advanced monitor features.

There is one video driver option that doesn't exist and would be helpful, namely to use a lower bus speed than the 100kb/sec standard. This would, I believe, resolve many communication errors with monitors whose DDC implementation is marginal. Several years ago there was an experimental branch in, IIRC, the i915 driver that lowered the bus speed, but it was never incorporated in the main branch.

@w8jcik
Copy link
Author

w8jcik commented Jun 26, 2024

Thank you for detailed explanation.

Adding --use-file-io switch didn't fix or break anything, as expected.

Are saying that you can use ddcci to change monitor brightness by writing to a /dev/bus/ddcci or just that , or just that were able to get it to install?

I only managed to set it up. It was not straightforward, most likely due to a bug. The current version of ddcci doesn't initialize any displays unless forced. Contrary to it's README. At least with Ubuntu 24.04 kernel.

Afterwards it still failed to work, although it generated some debug entries visible in my previous message.

There is one video driver option that doesn't exist and would be helpful, namely to use a lower bus speed [...]

I found your original discussion about the topic https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/37.

Looking at this branch https://github.com/vsyrjala/linux/tree/i2c_bus_speed I came up with following patch

diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c b/drivers/gpu/drm/i915/display/intel_gmbus.c
index e9e4dcf34..88aba021e 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.c
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.c
@@ -200,7 +200,7 @@ bool intel_gmbus_is_valid_pin(struct drm_i915_private *i915, unsigned int pin)
 
 /* Intel GPIO access functions */
 
-#define I2C_RISEFALL_TIME 10
+#define I2C_RISEFALL_TIME 5
 
 static inline struct intel_gmbus *
 to_intel_gmbus(struct i2c_adapter *i2c)
@@ -916,7 +916,7 @@ int intel_gmbus_setup(struct drm_i915_private *i915)
 		bus->adapter.retries = 1;
 
 		/* By default use a conservative clock rate */
-		bus->reg0 = pin | GMBUS_RATE_100KHZ;
+		bus->reg0 = pin | GMBUS_RATE_50KHZ;
 
 		/* gmbus seems to be broken on i830 */
 		if (IS_I830(i915))

After building of a current Ubuntu 24.04 LTS kernel (6.8.0-35) with the change

linux-buildinfo-6.8.0-35-generic_6.8.0-35.35+i2c50khz_amd64.deb
linux-cloud-tools-6.8.0-35_6.8.0-35.35+i2c50khz_amd64.deb
linux-cloud-tools-6.8.0-35-generic_6.8.0-35.35+i2c50khz_amd64.deb
linux-headers-6.8.0-35_6.8.0-35.35+i2c50khz_all.deb
linux-headers-6.8.0-35-generic_6.8.0-35.35+i2c50khz_amd64.deb
linux-image-unsigned-6.8.0-35-generic_6.8.0-35.35+i2c50khz_amd64.deb
linux-lib-rust-6.8.0-35-generic_6.8.0-35.35+i2c50khz_amd64.deb
linux-modules-6.8.0-35-generic_6.8.0-35.35+i2c50khz_amd64.deb
linux-modules-extra-6.8.0-35-generic_6.8.0-35.35+i2c50khz_amd64.deb
linux-modules-ipu6-6.8.0-35-generic_6.8.0-35.35+i2c50khz_amd64.deb
linux-modules-iwlwifi-6.8.0-35-generic_6.8.0-35.35+i2c50khz_amd64.deb
linux-modules-usbio-6.8.0-35-generic_6.8.0-35.35+i2c50khz_amd64.deb
linux-tools-6.8.0-35_6.8.0-35.35+i2c50khz_amd64.deb
linux-tools-6.8.0-35-generic_6.8.0-35.35+i2c50khz_amd64.deb

ddcutil is able to talk to the display 🥳

$ ddcutil detect
Display 1
   I2C bus:  /dev/i2c-3
   DRM connector:           card1-HDMI-A-2
   EDID synopsis:
      Mfg id:               DEL - Dell Inc.
      Model:                DELL 2209WA
      Product code:         61457  (0xf011)
      Serial number:        H735H99M2JRL
      Binary serial number: 843731532 (0x324a524c)
      Manufacture year:     2009,  Week: 39
   VCP version:         2.1
 ...

image

So it is all about the speed of I2C. Thank you a lot for help 😄

rockowitz/rockowitz.github.io#7

@rockowitz
Copy link
Owner

This is exciting! An actual example that can be referenced of DDC communication being fixed by lowering the bus speed!

The devil, of course, is in the details: what other changes are needed to make lowering the bus speed robust, how the speed change is communicated to the driver, etc. I will post an issue on the i915 freedesktop.org list, then you can follow up with the details of what you've done.

@rockowitz
Copy link
Owner

@w8jcik I created issue 11528 at freedesktop.org. Please comment on that issue with the details of your driver changes.

I would encourage those having DDC communication errors that ddcutil cannot resolve, particularly for marginal monitors, to add themselves to the interested parties on that issue and upvote the issue.

@rardiol
Copy link

rardiol commented Jun 29, 2024

This i915 patch also fixed both ddcutil and ddccontrol for me, AOC2217.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
monitor specific problems with particular monitors
Projects
None yet
Development

No branches or pull requests

3 participants