|
@@ -79,7 +79,7 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
|
|
struct gm200_i2c_aux *aux = gm200_i2c_aux(obj);
|
|
struct gm200_i2c_aux *aux = gm200_i2c_aux(obj);
|
|
struct nvkm_device *device = aux->base.pad->i2c->subdev.device;
|
|
struct nvkm_device *device = aux->base.pad->i2c->subdev.device;
|
|
const u32 base = aux->ch * 0x50;
|
|
const u32 base = aux->ch * 0x50;
|
|
- u32 ctrl, stat, timeout, retries;
|
|
|
|
|
|
+ u32 ctrl, stat, timeout, retries = 0;
|
|
u32 xbuf[4] = {};
|
|
u32 xbuf[4] = {};
|
|
int ret, i;
|
|
int ret, i;
|
|
|
|
|
|
@@ -111,7 +111,7 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
|
|
nvkm_wr32(device, 0x00d950 + base, addr);
|
|
nvkm_wr32(device, 0x00d950 + base, addr);
|
|
|
|
|
|
/* (maybe) retry transaction a number of times on failure... */
|
|
/* (maybe) retry transaction a number of times on failure... */
|
|
- for (retries = 0; !ret && retries < 32; retries++) {
|
|
|
|
|
|
+ do {
|
|
/* reset, and delay a while if this is a retry */
|
|
/* reset, and delay a while if this is a retry */
|
|
nvkm_wr32(device, 0x00d954 + base, 0x80000000 | ctrl);
|
|
nvkm_wr32(device, 0x00d954 + base, 0x80000000 | ctrl);
|
|
nvkm_wr32(device, 0x00d954 + base, 0x00000000 | ctrl);
|
|
nvkm_wr32(device, 0x00d954 + base, 0x00000000 | ctrl);
|
|
@@ -131,20 +131,20 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
} while (ctrl & 0x00010000);
|
|
} while (ctrl & 0x00010000);
|
|
- ret = 1;
|
|
|
|
|
|
+ ret = 0;
|
|
|
|
|
|
/* read status, and check if transaction completed ok */
|
|
/* read status, and check if transaction completed ok */
|
|
stat = nvkm_mask(device, 0x00d958 + base, 0, 0);
|
|
stat = nvkm_mask(device, 0x00d958 + base, 0, 0);
|
|
if ((stat & 0x000f0000) == 0x00080000 ||
|
|
if ((stat & 0x000f0000) == 0x00080000 ||
|
|
(stat & 0x000f0000) == 0x00020000)
|
|
(stat & 0x000f0000) == 0x00020000)
|
|
- ret = retry ? 0 : 1;
|
|
|
|
|
|
+ ret = 1;
|
|
if ((stat & 0x00000100))
|
|
if ((stat & 0x00000100))
|
|
ret = -ETIMEDOUT;
|
|
ret = -ETIMEDOUT;
|
|
if ((stat & 0x00000e00))
|
|
if ((stat & 0x00000e00))
|
|
ret = -EIO;
|
|
ret = -EIO;
|
|
|
|
|
|
AUX_TRACE(&aux->base, "%02d %08x %08x", retries, ctrl, stat);
|
|
AUX_TRACE(&aux->base, "%02d %08x %08x", retries, ctrl, stat);
|
|
- }
|
|
|
|
|
|
+ } while (ret && retry && retries++ < 32);
|
|
|
|
|
|
if (type & 1) {
|
|
if (type & 1) {
|
|
for (i = 0; i < 16; i += 4) {
|
|
for (i = 0; i < 16; i += 4) {
|