diff options
author | Keith Packard <keithp@keithp.com> | 2009-05-07 09:21:54 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2009-05-07 09:21:54 -0700 |
commit | 1d1a876ad932903cb32973cb72230d72d6792e33 (patch) | |
tree | a313052183eee90e14752cda6290ae26b1bbe033 | |
parent | abe80eadbed67b7c67b12183a2d552cee9d5cc50 (diff) |
Deal with I2C over DP AUX DEFER/NACK statusdisplay-port
-rw-r--r-- | src/i830_dp.c | 31 | ||||
-rw-r--r-- | src/i830_dp.h | 18 |
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 |