Skip to content

Commit c08bf04

Browse files
committed
lib: tenstorrent: bh_arc: dw_apb_i2c.c: init i2c only once
Initialize the I2C only once. Signed-off-by: Alex Apostolu <aapostolu@tenstorrent.com>
1 parent 529cd1a commit c08bf04

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

lib/tenstorrent/bh_arc/dw_apb_i2c.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ extern uint8_t asic_state;
155155
/* i2c_target_config for Zephyr callbacks in I2C slave mode */
156156
struct i2c_target_config i2c_target_config[3];
157157

158+
/* Static initialization flags for each I2C instance */
159+
static bool i2c_initialized[3] = {false, false, false};
160+
158161
static inline uint32_t GetI2CBaseAddress(uint32_t id)
159162
{
160163
switch (id) {
@@ -258,6 +261,11 @@ void I2CRecoverBus(uint32_t id)
258261
WriteReg(RESET_UNIT_I2C_CNTL_REG_ADDR, i2c_rst_cntl | BIT(id));
259262
/* Reenable I2C controller */
260263
WriteReg(GetI2CRegAddr(id, GET_I2C_OFFSET(IC_ENABLE)), 1);
264+
265+
/* Reset initialization flag for this instance after recovery */
266+
if (id < 3) {
267+
i2c_initialized[id] = false;
268+
}
261269
}
262270

263271
static void WaitTxFifoEmpty(uint32_t id)
@@ -417,6 +425,24 @@ void I2CInit(I2CMode mode, uint32_t slave_addr, I2CSpeedMode speed, uint32_t id)
417425
return;
418426
}
419427

428+
/* Check if this I2C instance is already initialized */
429+
if (id < 3 && i2c_initialized[id]) {
430+
/* Only update target address if it's different */
431+
if (mode == I2CMst) {
432+
uint32_t current_tar = ReadReg(GetI2CRegAddr(id, GET_I2C_OFFSET(IC_TAR))) &
433+
DW_APB_I2C_IC_TAR_IC_TAR_MASK;
434+
if (current_tar != (slave_addr & DW_APB_I2C_IC_TAR_IC_TAR_MASK)) {
435+
WriteReg(GetI2CRegAddr(id, GET_I2C_OFFSET(IC_ENABLE)), 0);
436+
Wait(10 * WAIT_1US);
437+
WriteReg(GetI2CRegAddr(id, GET_I2C_OFFSET(IC_TAR)),
438+
slave_addr & DW_APB_I2C_IC_TAR_IC_TAR_MASK);
439+
WriteReg(GetI2CRegAddr(id, GET_I2C_OFFSET(IC_ENABLE)), 1);
440+
Wait(10 * WAIT_1US);
441+
}
442+
}
443+
return;
444+
}
445+
420446
WaitTxFifoEmpty(id);
421447
WaitMasterIdle(id);
422448

@@ -469,6 +495,11 @@ void I2CInit(I2CMode mode, uint32_t slave_addr, I2CSpeedMode speed, uint32_t id)
469495

470496
WriteReg(GetI2CRegAddr(id, GET_I2C_OFFSET(IC_ENABLE)), 1);
471497
Wait(10 * WAIT_1US);
498+
499+
/* Mark this I2C instance as initialized */
500+
if (id < 3) {
501+
i2c_initialized[id] = true;
502+
}
472503
}
473504

474505
/* Resets the all I2C controller instances */
@@ -480,6 +511,11 @@ void I2CReset(void)
480511
Wait(WAIT_1US);
481512
WriteReg(RESET_UNIT_I2C_CNTL_REG_ADDR, i2c_cntl & ~RESET_UNIT_I2C_CNTL_RESET_MASK);
482513
Wait(WAIT_1US);
514+
515+
/* Reset initialization flags after hardware reset */
516+
for (int i = 0; i < 3; i++) {
517+
i2c_initialized[i] = false;
518+
}
483519
}
484520

485521
/* Generalized transaction function called by I2CWriteBytes and I2CReadBytes, implements SMBUS write

0 commit comments

Comments
 (0)