summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2009-05-07 09:21:54 -0700
committerKeith Packard <keithp@keithp.com>2009-05-07 09:21:54 -0700
commit1d1a876ad932903cb32973cb72230d72d6792e33 (patch)
treea313052183eee90e14752cda6290ae26b1bbe033
parentabe80eadbed67b7c67b12183a2d552cee9d5cc50 (diff)
Deal with I2C over DP AUX DEFER/NACK statusdisplay-port
-rw-r--r--src/i830_dp.c31
-rw-r--r--src/i830_dp.h18
2 files changed, 35 insertions, 14 deletions
diff --git a/src/i830_dp.c b/src/i830_dp.c
index a4018df5..3a725256 100644
--- a/src/i830_dp.c
+++ b/src/i830_dp.c
@@ -167,6 +167,11 @@ i830_dp_aux_ch(ScrnInfoPtr pScrn, uint32_t output_reg,
uint32_t ctl;
uint32_t status;
+// ErrorF("dp_aux_ch 0x%08x send %d:",
+// output_reg, send_bytes);
+// for (i = 0; i < send_bytes; i++)
+// ErrorF(" %02x", send[i]);
+// ErrorF("\n");
/* Load the send data into the aux channel data registers */
for (i = 0; i < send_bytes; i += 4) {
uint32_t d = pack_aux(send + i, send_bytes - i);;
@@ -187,6 +192,8 @@ i830_dp_aux_ch(ScrnInfoPtr pScrn, uint32_t output_reg,
DP_AUX_CH_CTL_TIME_OUT_ERROR |
DP_AUX_CH_CTL_RECEIVE_ERROR);
+// ErrorF("out ch_ctl 0x%08x 0x%08x\n", ch_ctl, ctl);
+
/* Send the command and wait for it to complete */
OUTREG(ch_ctl, ctl);
for (;;) {
@@ -213,8 +220,10 @@ i830_dp_aux_ch(ScrnInfoPtr pScrn, uint32_t output_reg,
/* Check for timeout or receive error.
* Timeouts occur when the sink is not connected
*/
- if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR | DP_AUX_CH_CTL_RECEIVE_ERROR))
+ if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR | DP_AUX_CH_CTL_RECEIVE_ERROR)) {
+ ErrorF("dp_aux_ch error status 0x%08x\n", status);
return -1;
+ }
/* Unload any bytes sent back from the other side */
recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >>
@@ -225,9 +234,14 @@ i830_dp_aux_ch(ScrnInfoPtr pScrn, uint32_t output_reg,
for (i = 0; i < recv_bytes; i += 4) {
uint32_t d = INREG(ch_data + i);
+// ErrorF("bytes %d-%d: 0x%08x\n", i, i + 3, d);
unpack_aux(d, recv + i, recv_bytes - i);
}
+// ErrorF(" 0x%08x: %d:", status, recv_bytes);
+// for (i = 0; i < recv_bytes; i ++)
+// ErrorF(" %02x", recv[i]);
+// ErrorF("\n");
return recv_bytes;
}
@@ -377,14 +391,21 @@ i830_dp_aux_i2c_transaction(ScrnInfoPtr pScrn, uint32_t output_reg,
"i2c_read: aux_ch error %d\n", ret);
return -1;
}
- if ((reply[0] & AUX_I2C_REPLY_MASK) == AUX_I2C_REPLY_ACK) {
+ switch (reply[0] & AUX_I2C_REPLY_MASK) {
+ case AUX_I2C_REPLY_ACK:
if (mode == aux_i2c_read)
*read_byte = reply[1];
return reply_bytes - 1;
- }
- else if ((reply[0] & AUX_I2C_REPLY_MASK) == AUX_I2C_REPLY_DEFER)
+ case AUX_I2C_REPLY_DEFER:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "aux ch i2c defer\n");
usleep(100);
- else {
+ break;
+ case AUX_I2C_REPLY_NACK:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "aux ch i2c nack\n");
+ return 0;
+ default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"aux ch i2c write returns %02x\n", reply[0]);
return -1;
diff --git a/src/i830_dp.h b/src/i830_dp.h
index 852f28b3..4eab2371 100644
--- a/src/i830_dp.h
+++ b/src/i830_dp.h
@@ -29,15 +29,15 @@
#define AUX_I2C_STATUS 0x2
#define AUX_I2C_MOT 0x4
-#define AUX_NATIVE_REPLY_ACK 0x0
-#define AUX_NATIVE_REPLY_NACK 0x1
-#define AUX_NATIVE_REPLY_DEFER 0x2
-#define AUX_NATIVE_REPLY_MASK 0x3
-
-#define AUX_I2C_REPLY_ACK (0x0 << 2)
-#define AUX_I2C_REPLY_NACK (0x1 << 2)
-#define AUX_I2C_REPLY_DEFER (0x2 << 2)
-#define AUX_I2C_REPLY_MASK (0x3 << 2)
+#define AUX_NATIVE_REPLY_ACK (0x0 << 4)
+#define AUX_NATIVE_REPLY_NACK (0x1 << 4)
+#define AUX_NATIVE_REPLY_DEFER (0x2 << 4)
+#define AUX_NATIVE_REPLY_MASK (0x3 << 4)
+
+#define AUX_I2C_REPLY_ACK (0x0 << 6)
+#define AUX_I2C_REPLY_NACK (0x1 << 6)
+#define AUX_I2C_REPLY_DEFER (0x2 << 6)
+#define AUX_I2C_REPLY_MASK (0x3 << 6)
/* AUX CH addresses */
#define DP_LINK_BW_SET 0x100