Commit caae745a authored by Benson Leung's avatar Benson Leung Committed by Daniel Vetter

drm/i915: Fix single msg gmbus_xfers writes

gmbus_xfer with a single message (particularly a single message write) would
set Bus Cycle Select to 100b, the Gen Stop cycle, instead of 101b,
No Index, Stop cycle. This would not start single message i2c transactions.

Also, gmbus_xfer done: will disable the interface without checking if
it is idle. In the case of writes, there will be no wait on status or delay
to ensure the write starts and completes before the interface is turned off.

Fixed the former issue by using the same cycle selection as used in the
I2C_M_RD for the write case.
GMBUS_CYCLE_WAIT | (i + 1 == num ? GMBUS_CYCLE_STOP : 0)
Fixed the latter by waiting on GMBUS_ACTIVE to deassert before disable.

Note from the grumpy d-i-n maintainer: The first hunk that changes the
gmbus read path is just cosmetics to align the code with the write
path.  I.e. the commit message above is slightly lying because the
first issue is _only_ with writes (and not simply "particularly").
Signed-off-by: default avatarBenson Leung <bleung@chromium.org>
Reviewed-by: default avatarDaniel Kurtz <djkurtz@chromium.org>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 5d1333fc
...@@ -253,7 +253,8 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -253,7 +253,8 @@ gmbus_xfer(struct i2c_adapter *adapter,
if (msgs[i].flags & I2C_M_RD) { if (msgs[i].flags & I2C_M_RD) {
I915_WRITE(GMBUS1 + reg_offset, I915_WRITE(GMBUS1 + reg_offset,
GMBUS_CYCLE_WAIT | (i + 1 == num ? GMBUS_CYCLE_STOP : 0) | GMBUS_CYCLE_WAIT |
(i + 1 == num ? GMBUS_CYCLE_STOP : 0) |
(len << GMBUS_BYTE_COUNT_SHIFT) | (len << GMBUS_BYTE_COUNT_SHIFT) |
(msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) |
GMBUS_SLAVE_READ | GMBUS_SW_RDY); GMBUS_SLAVE_READ | GMBUS_SW_RDY);
...@@ -282,7 +283,8 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -282,7 +283,8 @@ gmbus_xfer(struct i2c_adapter *adapter,
I915_WRITE(GMBUS3 + reg_offset, val); I915_WRITE(GMBUS3 + reg_offset, val);
I915_WRITE(GMBUS1 + reg_offset, I915_WRITE(GMBUS1 + reg_offset,
(i + 1 == num ? GMBUS_CYCLE_STOP : GMBUS_CYCLE_WAIT) | GMBUS_CYCLE_WAIT |
(i + 1 == num ? GMBUS_CYCLE_STOP : 0) |
(msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) | (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) |
(msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) |
GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
...@@ -321,9 +323,12 @@ gmbus_xfer(struct i2c_adapter *adapter, ...@@ -321,9 +323,12 @@ gmbus_xfer(struct i2c_adapter *adapter,
I915_WRITE(GMBUS1 + reg_offset, 0); I915_WRITE(GMBUS1 + reg_offset, 0);
done: done:
/* Mark the GMBUS interface as disabled. We will re-enable it at the /* Mark the GMBUS interface as disabled after waiting for idle.
* start of the next xfer, till then let it sleep. * We will re-enable it at the start of the next xfer,
* till then let it sleep.
*/ */
if (wait_for((I915_READ(GMBUS2 + reg_offset) & GMBUS_ACTIVE) == 0, 10))
DRM_INFO("GMBUS timed out waiting for idle\n");
I915_WRITE(GMBUS0 + reg_offset, 0); I915_WRITE(GMBUS0 + reg_offset, 0);
ret = i; ret = i;
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment