1*7e4d5620SIcenowy Zheng /* 2*7e4d5620SIcenowy Zheng * Copyright (C) 2018 Marvell International Ltd. 3*7e4d5620SIcenowy Zheng * Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.io> 4*7e4d5620SIcenowy Zheng * 5*7e4d5620SIcenowy Zheng * SPDX-License-Identifier: BSD-3-Clause 6*7e4d5620SIcenowy Zheng * https://spdx.org/licenses 7*7e4d5620SIcenowy Zheng */ 8*7e4d5620SIcenowy Zheng 9*7e4d5620SIcenowy Zheng /* 10*7e4d5620SIcenowy Zheng * This driver is for Mentor Graphics Inventra MI2CV IP core, which is used 11*7e4d5620SIcenowy Zheng * for Marvell and Allwinner SoCs in ATF. 12*7e4d5620SIcenowy Zheng */ 13*7e4d5620SIcenowy Zheng 14*7e4d5620SIcenowy Zheng #include <debug.h> 15*7e4d5620SIcenowy Zheng #include <delay_timer.h> 16*7e4d5620SIcenowy Zheng #include <errno.h> 17*7e4d5620SIcenowy Zheng #include <mentor/mi2cv.h> 18*7e4d5620SIcenowy Zheng #include <mmio.h> 19*7e4d5620SIcenowy Zheng 20*7e4d5620SIcenowy Zheng #if LOG_LEVEL >= LOG_LEVEL_VERBOSE 21*7e4d5620SIcenowy Zheng #define DEBUG_I2C 22*7e4d5620SIcenowy Zheng #endif 23*7e4d5620SIcenowy Zheng 24*7e4d5620SIcenowy Zheng #define I2C_TIMEOUT_VALUE 0x500 25*7e4d5620SIcenowy Zheng #define I2C_MAX_RETRY_CNT 1000 26*7e4d5620SIcenowy Zheng #define I2C_CMD_WRITE 0x0 27*7e4d5620SIcenowy Zheng #define I2C_CMD_READ 0x1 28*7e4d5620SIcenowy Zheng 29*7e4d5620SIcenowy Zheng #define I2C_DATA_ADDR_7BIT_OFFS 0x1 30*7e4d5620SIcenowy Zheng #define I2C_DATA_ADDR_7BIT_MASK (0xFF << I2C_DATA_ADDR_7BIT_OFFS) 31*7e4d5620SIcenowy Zheng 32*7e4d5620SIcenowy Zheng #define I2C_CONTROL_ACK 0x00000004 33*7e4d5620SIcenowy Zheng #define I2C_CONTROL_IFLG 0x00000008 34*7e4d5620SIcenowy Zheng #define I2C_CONTROL_STOP 0x00000010 35*7e4d5620SIcenowy Zheng #define I2C_CONTROL_START 0x00000020 36*7e4d5620SIcenowy Zheng #define I2C_CONTROL_TWSIEN 0x00000040 37*7e4d5620SIcenowy Zheng #define I2C_CONTROL_INTEN 0x00000080 38*7e4d5620SIcenowy Zheng 39*7e4d5620SIcenowy Zheng #define I2C_STATUS_START 0x08 40*7e4d5620SIcenowy Zheng #define I2C_STATUS_REPEATED_START 0x10 41*7e4d5620SIcenowy Zheng #define I2C_STATUS_ADDR_W_ACK 0x18 42*7e4d5620SIcenowy Zheng #define I2C_STATUS_DATA_W_ACK 0x28 43*7e4d5620SIcenowy Zheng #define I2C_STATUS_LOST_ARB_DATA_ADDR_TRANSFER 0x38 44*7e4d5620SIcenowy Zheng #define I2C_STATUS_ADDR_R_ACK 0x40 45*7e4d5620SIcenowy Zheng #define I2C_STATUS_DATA_R_ACK 0x50 46*7e4d5620SIcenowy Zheng #define I2C_STATUS_DATA_R_NAK 0x58 47*7e4d5620SIcenowy Zheng #define I2C_STATUS_LOST_ARB_GENERAL_CALL 0x78 48*7e4d5620SIcenowy Zheng #define I2C_STATUS_IDLE 0xF8 49*7e4d5620SIcenowy Zheng 50*7e4d5620SIcenowy Zheng #define I2C_UNSTUCK_TRIGGER 0x1 51*7e4d5620SIcenowy Zheng #define I2C_UNSTUCK_ONGOING 0x2 52*7e4d5620SIcenowy Zheng #define I2C_UNSTUCK_ERROR 0x4 53*7e4d5620SIcenowy Zheng 54*7e4d5620SIcenowy Zheng static struct mentor_i2c_regs *base; 55*7e4d5620SIcenowy Zheng 56*7e4d5620SIcenowy Zheng static int mentor_i2c_lost_arbitration(uint32_t *status) 57*7e4d5620SIcenowy Zheng { 58*7e4d5620SIcenowy Zheng *status = mmio_read_32((uintptr_t)&base->status); 59*7e4d5620SIcenowy Zheng if ((*status == I2C_STATUS_LOST_ARB_DATA_ADDR_TRANSFER) || 60*7e4d5620SIcenowy Zheng (*status == I2C_STATUS_LOST_ARB_GENERAL_CALL)) 61*7e4d5620SIcenowy Zheng return -EAGAIN; 62*7e4d5620SIcenowy Zheng 63*7e4d5620SIcenowy Zheng return 0; 64*7e4d5620SIcenowy Zheng } 65*7e4d5620SIcenowy Zheng 66*7e4d5620SIcenowy Zheng static void mentor_i2c_interrupt_clear(void) 67*7e4d5620SIcenowy Zheng { 68*7e4d5620SIcenowy Zheng uint32_t reg; 69*7e4d5620SIcenowy Zheng 70*7e4d5620SIcenowy Zheng reg = mmio_read_32((uintptr_t)&base->control); 71*7e4d5620SIcenowy Zheng reg &= ~(I2C_CONTROL_IFLG); 72*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->control, reg); 73*7e4d5620SIcenowy Zheng /* Wait for 1 us for the clear to take effect */ 74*7e4d5620SIcenowy Zheng udelay(1); 75*7e4d5620SIcenowy Zheng } 76*7e4d5620SIcenowy Zheng 77*7e4d5620SIcenowy Zheng static int mentor_i2c_interrupt_get(void) 78*7e4d5620SIcenowy Zheng { 79*7e4d5620SIcenowy Zheng uint32_t reg; 80*7e4d5620SIcenowy Zheng 81*7e4d5620SIcenowy Zheng /* get the interrupt flag bit */ 82*7e4d5620SIcenowy Zheng reg = mmio_read_32((uintptr_t)&base->control); 83*7e4d5620SIcenowy Zheng reg &= I2C_CONTROL_IFLG; 84*7e4d5620SIcenowy Zheng return reg && I2C_CONTROL_IFLG; 85*7e4d5620SIcenowy Zheng } 86*7e4d5620SIcenowy Zheng 87*7e4d5620SIcenowy Zheng static int mentor_i2c_wait_interrupt(void) 88*7e4d5620SIcenowy Zheng { 89*7e4d5620SIcenowy Zheng uint32_t timeout = 0; 90*7e4d5620SIcenowy Zheng 91*7e4d5620SIcenowy Zheng while (!mentor_i2c_interrupt_get() && (timeout++ < I2C_TIMEOUT_VALUE)) 92*7e4d5620SIcenowy Zheng ; 93*7e4d5620SIcenowy Zheng if (timeout >= I2C_TIMEOUT_VALUE) 94*7e4d5620SIcenowy Zheng return -ETIMEDOUT; 95*7e4d5620SIcenowy Zheng 96*7e4d5620SIcenowy Zheng return 0; 97*7e4d5620SIcenowy Zheng } 98*7e4d5620SIcenowy Zheng 99*7e4d5620SIcenowy Zheng static int mentor_i2c_start_bit_set(void) 100*7e4d5620SIcenowy Zheng { 101*7e4d5620SIcenowy Zheng int is_int_flag = 0; 102*7e4d5620SIcenowy Zheng uint32_t status; 103*7e4d5620SIcenowy Zheng 104*7e4d5620SIcenowy Zheng if (mentor_i2c_interrupt_get()) 105*7e4d5620SIcenowy Zheng is_int_flag = 1; 106*7e4d5620SIcenowy Zheng 107*7e4d5620SIcenowy Zheng /* set start bit */ 108*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->control, 109*7e4d5620SIcenowy Zheng mmio_read_32((uintptr_t)&base->control) | 110*7e4d5620SIcenowy Zheng I2C_CONTROL_START); 111*7e4d5620SIcenowy Zheng 112*7e4d5620SIcenowy Zheng /* in case that the int flag was set before i.e. repeated start bit */ 113*7e4d5620SIcenowy Zheng if (is_int_flag) { 114*7e4d5620SIcenowy Zheng VERBOSE("%s: repeated start Bit\n", __func__); 115*7e4d5620SIcenowy Zheng mentor_i2c_interrupt_clear(); 116*7e4d5620SIcenowy Zheng } 117*7e4d5620SIcenowy Zheng 118*7e4d5620SIcenowy Zheng if (mentor_i2c_wait_interrupt()) { 119*7e4d5620SIcenowy Zheng ERROR("Start clear bit timeout\n"); 120*7e4d5620SIcenowy Zheng return -ETIMEDOUT; 121*7e4d5620SIcenowy Zheng } 122*7e4d5620SIcenowy Zheng 123*7e4d5620SIcenowy Zheng /* check that start bit went down */ 124*7e4d5620SIcenowy Zheng if ((mmio_read_32((uintptr_t)&base->control) & 125*7e4d5620SIcenowy Zheng I2C_CONTROL_START) != 0) { 126*7e4d5620SIcenowy Zheng ERROR("Start bit didn't went down\n"); 127*7e4d5620SIcenowy Zheng return -EPERM; 128*7e4d5620SIcenowy Zheng } 129*7e4d5620SIcenowy Zheng 130*7e4d5620SIcenowy Zheng /* check the status */ 131*7e4d5620SIcenowy Zheng if (mentor_i2c_lost_arbitration(&status)) { 132*7e4d5620SIcenowy Zheng ERROR("%s - %d: Lost arbitration, got status %x\n", 133*7e4d5620SIcenowy Zheng __func__, __LINE__, status); 134*7e4d5620SIcenowy Zheng return -EAGAIN; 135*7e4d5620SIcenowy Zheng } 136*7e4d5620SIcenowy Zheng if ((status != I2C_STATUS_START) && 137*7e4d5620SIcenowy Zheng (status != I2C_STATUS_REPEATED_START)) { 138*7e4d5620SIcenowy Zheng ERROR("Got status %x after enable start bit.\n", status); 139*7e4d5620SIcenowy Zheng return -EPERM; 140*7e4d5620SIcenowy Zheng } 141*7e4d5620SIcenowy Zheng 142*7e4d5620SIcenowy Zheng return 0; 143*7e4d5620SIcenowy Zheng } 144*7e4d5620SIcenowy Zheng 145*7e4d5620SIcenowy Zheng static int mentor_i2c_stop_bit_set(void) 146*7e4d5620SIcenowy Zheng { 147*7e4d5620SIcenowy Zheng int timeout; 148*7e4d5620SIcenowy Zheng uint32_t status; 149*7e4d5620SIcenowy Zheng 150*7e4d5620SIcenowy Zheng /* Generate stop bit */ 151*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->control, 152*7e4d5620SIcenowy Zheng mmio_read_32((uintptr_t)&base->control) | 153*7e4d5620SIcenowy Zheng I2C_CONTROL_STOP); 154*7e4d5620SIcenowy Zheng mentor_i2c_interrupt_clear(); 155*7e4d5620SIcenowy Zheng 156*7e4d5620SIcenowy Zheng timeout = 0; 157*7e4d5620SIcenowy Zheng /* Read control register, check the control stop bit */ 158*7e4d5620SIcenowy Zheng while ((mmio_read_32((uintptr_t)&base->control) & I2C_CONTROL_STOP) && 159*7e4d5620SIcenowy Zheng (timeout++ < I2C_TIMEOUT_VALUE)) 160*7e4d5620SIcenowy Zheng ; 161*7e4d5620SIcenowy Zheng if (timeout >= I2C_TIMEOUT_VALUE) { 162*7e4d5620SIcenowy Zheng ERROR("Stop bit didn't went down\n"); 163*7e4d5620SIcenowy Zheng return -ETIMEDOUT; 164*7e4d5620SIcenowy Zheng } 165*7e4d5620SIcenowy Zheng 166*7e4d5620SIcenowy Zheng /* check that stop bit went down */ 167*7e4d5620SIcenowy Zheng if ((mmio_read_32((uintptr_t)&base->control) & I2C_CONTROL_STOP) != 0) { 168*7e4d5620SIcenowy Zheng ERROR("Stop bit didn't went down\n"); 169*7e4d5620SIcenowy Zheng return -EPERM; 170*7e4d5620SIcenowy Zheng } 171*7e4d5620SIcenowy Zheng 172*7e4d5620SIcenowy Zheng /* check the status */ 173*7e4d5620SIcenowy Zheng if (mentor_i2c_lost_arbitration(&status)) { 174*7e4d5620SIcenowy Zheng ERROR("%s - %d: Lost arbitration, got status %x\n", 175*7e4d5620SIcenowy Zheng __func__, __LINE__, status); 176*7e4d5620SIcenowy Zheng return -EAGAIN; 177*7e4d5620SIcenowy Zheng } 178*7e4d5620SIcenowy Zheng if (status != I2C_STATUS_IDLE) { 179*7e4d5620SIcenowy Zheng ERROR("Got status %x after enable stop bit.\n", status); 180*7e4d5620SIcenowy Zheng return -EPERM; 181*7e4d5620SIcenowy Zheng } 182*7e4d5620SIcenowy Zheng 183*7e4d5620SIcenowy Zheng return 0; 184*7e4d5620SIcenowy Zheng } 185*7e4d5620SIcenowy Zheng 186*7e4d5620SIcenowy Zheng static int mentor_i2c_address_set(uint8_t chain, int command) 187*7e4d5620SIcenowy Zheng { 188*7e4d5620SIcenowy Zheng uint32_t reg, status; 189*7e4d5620SIcenowy Zheng 190*7e4d5620SIcenowy Zheng reg = (chain << I2C_DATA_ADDR_7BIT_OFFS) & I2C_DATA_ADDR_7BIT_MASK; 191*7e4d5620SIcenowy Zheng reg |= command; 192*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->data, reg); 193*7e4d5620SIcenowy Zheng udelay(1); 194*7e4d5620SIcenowy Zheng 195*7e4d5620SIcenowy Zheng mentor_i2c_interrupt_clear(); 196*7e4d5620SIcenowy Zheng 197*7e4d5620SIcenowy Zheng if (mentor_i2c_wait_interrupt()) { 198*7e4d5620SIcenowy Zheng ERROR("Start clear bit timeout\n"); 199*7e4d5620SIcenowy Zheng return -ETIMEDOUT; 200*7e4d5620SIcenowy Zheng } 201*7e4d5620SIcenowy Zheng 202*7e4d5620SIcenowy Zheng /* check the status */ 203*7e4d5620SIcenowy Zheng if (mentor_i2c_lost_arbitration(&status)) { 204*7e4d5620SIcenowy Zheng ERROR("%s - %d: Lost arbitration, got status %x\n", 205*7e4d5620SIcenowy Zheng __func__, __LINE__, status); 206*7e4d5620SIcenowy Zheng return -EAGAIN; 207*7e4d5620SIcenowy Zheng } 208*7e4d5620SIcenowy Zheng if (((status != I2C_STATUS_ADDR_R_ACK) && (command == I2C_CMD_READ)) || 209*7e4d5620SIcenowy Zheng ((status != I2C_STATUS_ADDR_W_ACK) && (command == I2C_CMD_WRITE))) { 210*7e4d5620SIcenowy Zheng /* only in debug, since in boot we try to read the SPD 211*7e4d5620SIcenowy Zheng * of both DRAM, and we don't want error messages in cas 212*7e4d5620SIcenowy Zheng * DIMM doesn't exist. 213*7e4d5620SIcenowy Zheng */ 214*7e4d5620SIcenowy Zheng INFO("%s: ERROR - status %x addr in %s mode.\n", __func__, 215*7e4d5620SIcenowy Zheng status, (command == I2C_CMD_WRITE) ? "Write" : "Read"); 216*7e4d5620SIcenowy Zheng return -EPERM; 217*7e4d5620SIcenowy Zheng } 218*7e4d5620SIcenowy Zheng 219*7e4d5620SIcenowy Zheng return 0; 220*7e4d5620SIcenowy Zheng } 221*7e4d5620SIcenowy Zheng 222*7e4d5620SIcenowy Zheng /* 223*7e4d5620SIcenowy Zheng * The I2C module contains a clock divider to generate the SCL clock. 224*7e4d5620SIcenowy Zheng * This function calculates and sets the <N> and <M> fields in the I2C Baud 225*7e4d5620SIcenowy Zheng * Rate Register (t=01) to obtain given 'requested_speed'. 226*7e4d5620SIcenowy Zheng * The requested_speed will be equal to: 227*7e4d5620SIcenowy Zheng * CONFIG_SYS_TCLK / (10 * (M + 1) * (2 << N)) 228*7e4d5620SIcenowy Zheng * Where M is the value represented by bits[6:3] and N is the value represented 229*7e4d5620SIcenowy Zheng * by bits[2:0] of "I2C Baud Rate Register". 230*7e4d5620SIcenowy Zheng * Therefore max M which can be set is 16 (2^4) and max N is 8 (2^3). So the 231*7e4d5620SIcenowy Zheng * lowest possible baudrate is: 232*7e4d5620SIcenowy Zheng * CONFIG_SYS_TCLK/(10 * (16 +1) * (2 << 8), which equals to: 233*7e4d5620SIcenowy Zheng * CONFIG_SYS_TCLK/87040. Assuming that CONFIG_SYS_TCLK=250MHz, the lowest 234*7e4d5620SIcenowy Zheng * possible frequency is ~2,872KHz. 235*7e4d5620SIcenowy Zheng */ 236*7e4d5620SIcenowy Zheng static unsigned int mentor_i2c_bus_speed_set(unsigned int requested_speed) 237*7e4d5620SIcenowy Zheng { 238*7e4d5620SIcenowy Zheng unsigned int n, m, freq, margin, min_margin = 0xffffffff; 239*7e4d5620SIcenowy Zheng unsigned int actual_n = 0, actual_m = 0; 240*7e4d5620SIcenowy Zheng int val; 241*7e4d5620SIcenowy Zheng 242*7e4d5620SIcenowy Zheng /* Calculate N and M for the TWSI clock baud rate */ 243*7e4d5620SIcenowy Zheng for (n = 0; n < 8; n++) { 244*7e4d5620SIcenowy Zheng for (m = 0; m < 16; m++) { 245*7e4d5620SIcenowy Zheng freq = CONFIG_SYS_TCLK / (10 * (m + 1) * (2 << n)); 246*7e4d5620SIcenowy Zheng val = requested_speed - freq; 247*7e4d5620SIcenowy Zheng margin = (val > 0) ? val : -val; 248*7e4d5620SIcenowy Zheng 249*7e4d5620SIcenowy Zheng if ((freq <= requested_speed) && 250*7e4d5620SIcenowy Zheng (margin < min_margin)) { 251*7e4d5620SIcenowy Zheng min_margin = margin; 252*7e4d5620SIcenowy Zheng actual_n = n; 253*7e4d5620SIcenowy Zheng actual_m = m; 254*7e4d5620SIcenowy Zheng } 255*7e4d5620SIcenowy Zheng } 256*7e4d5620SIcenowy Zheng } 257*7e4d5620SIcenowy Zheng VERBOSE("%s: actual_n = %u, actual_m = %u\n", 258*7e4d5620SIcenowy Zheng __func__, actual_n, actual_m); 259*7e4d5620SIcenowy Zheng /* Set the baud rate */ 260*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->baudrate, (actual_m << 3) | actual_n); 261*7e4d5620SIcenowy Zheng 262*7e4d5620SIcenowy Zheng return 0; 263*7e4d5620SIcenowy Zheng } 264*7e4d5620SIcenowy Zheng 265*7e4d5620SIcenowy Zheng #ifdef DEBUG_I2C 266*7e4d5620SIcenowy Zheng static int mentor_i2c_probe(uint8_t chip) 267*7e4d5620SIcenowy Zheng { 268*7e4d5620SIcenowy Zheng int ret = 0; 269*7e4d5620SIcenowy Zheng 270*7e4d5620SIcenowy Zheng ret = mentor_i2c_start_bit_set(); 271*7e4d5620SIcenowy Zheng if (ret != 0) { 272*7e4d5620SIcenowy Zheng mentor_i2c_stop_bit_set(); 273*7e4d5620SIcenowy Zheng ERROR("%s - %d: %s", __func__, __LINE__, 274*7e4d5620SIcenowy Zheng "mentor_i2c_start_bit_set failed\n"); 275*7e4d5620SIcenowy Zheng return -EPERM; 276*7e4d5620SIcenowy Zheng } 277*7e4d5620SIcenowy Zheng 278*7e4d5620SIcenowy Zheng ret = mentor_i2c_address_set(chip, I2C_CMD_WRITE); 279*7e4d5620SIcenowy Zheng if (ret != 0) { 280*7e4d5620SIcenowy Zheng mentor_i2c_stop_bit_set(); 281*7e4d5620SIcenowy Zheng ERROR("%s - %d: %s", __func__, __LINE__, 282*7e4d5620SIcenowy Zheng "mentor_i2c_address_set failed\n"); 283*7e4d5620SIcenowy Zheng return -EPERM; 284*7e4d5620SIcenowy Zheng } 285*7e4d5620SIcenowy Zheng 286*7e4d5620SIcenowy Zheng mentor_i2c_stop_bit_set(); 287*7e4d5620SIcenowy Zheng 288*7e4d5620SIcenowy Zheng VERBOSE("%s: successful I2C probe\n", __func__); 289*7e4d5620SIcenowy Zheng 290*7e4d5620SIcenowy Zheng return ret; 291*7e4d5620SIcenowy Zheng } 292*7e4d5620SIcenowy Zheng #endif 293*7e4d5620SIcenowy Zheng 294*7e4d5620SIcenowy Zheng /* regular i2c transaction */ 295*7e4d5620SIcenowy Zheng static int mentor_i2c_data_receive(uint8_t *p_block, uint32_t block_size) 296*7e4d5620SIcenowy Zheng { 297*7e4d5620SIcenowy Zheng uint32_t reg, status, block_size_read = block_size; 298*7e4d5620SIcenowy Zheng 299*7e4d5620SIcenowy Zheng /* Wait for cause interrupt */ 300*7e4d5620SIcenowy Zheng if (mentor_i2c_wait_interrupt()) { 301*7e4d5620SIcenowy Zheng ERROR("Start clear bit timeout\n"); 302*7e4d5620SIcenowy Zheng return -ETIMEDOUT; 303*7e4d5620SIcenowy Zheng } 304*7e4d5620SIcenowy Zheng while (block_size_read) { 305*7e4d5620SIcenowy Zheng if (block_size_read == 1) { 306*7e4d5620SIcenowy Zheng reg = mmio_read_32((uintptr_t)&base->control); 307*7e4d5620SIcenowy Zheng reg &= ~(I2C_CONTROL_ACK); 308*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->control, reg); 309*7e4d5620SIcenowy Zheng } 310*7e4d5620SIcenowy Zheng mentor_i2c_interrupt_clear(); 311*7e4d5620SIcenowy Zheng 312*7e4d5620SIcenowy Zheng if (mentor_i2c_wait_interrupt()) { 313*7e4d5620SIcenowy Zheng ERROR("Start clear bit timeout\n"); 314*7e4d5620SIcenowy Zheng return -ETIMEDOUT; 315*7e4d5620SIcenowy Zheng } 316*7e4d5620SIcenowy Zheng /* check the status */ 317*7e4d5620SIcenowy Zheng if (mentor_i2c_lost_arbitration(&status)) { 318*7e4d5620SIcenowy Zheng ERROR("%s - %d: Lost arbitration, got status %x\n", 319*7e4d5620SIcenowy Zheng __func__, __LINE__, status); 320*7e4d5620SIcenowy Zheng return -EAGAIN; 321*7e4d5620SIcenowy Zheng } 322*7e4d5620SIcenowy Zheng if ((status != I2C_STATUS_DATA_R_ACK) && 323*7e4d5620SIcenowy Zheng (block_size_read != 1)) { 324*7e4d5620SIcenowy Zheng ERROR("Status %x in read transaction\n", status); 325*7e4d5620SIcenowy Zheng return -EPERM; 326*7e4d5620SIcenowy Zheng } 327*7e4d5620SIcenowy Zheng if ((status != I2C_STATUS_DATA_R_NAK) && 328*7e4d5620SIcenowy Zheng (block_size_read == 1)) { 329*7e4d5620SIcenowy Zheng ERROR("Status %x in Rd Terminate\n", status); 330*7e4d5620SIcenowy Zheng return -EPERM; 331*7e4d5620SIcenowy Zheng } 332*7e4d5620SIcenowy Zheng 333*7e4d5620SIcenowy Zheng /* read the data */ 334*7e4d5620SIcenowy Zheng *p_block = (uint8_t) mmio_read_32((uintptr_t)&base->data); 335*7e4d5620SIcenowy Zheng VERBOSE("%s: place %d read %x\n", __func__, 336*7e4d5620SIcenowy Zheng block_size - block_size_read, *p_block); 337*7e4d5620SIcenowy Zheng p_block++; 338*7e4d5620SIcenowy Zheng block_size_read--; 339*7e4d5620SIcenowy Zheng } 340*7e4d5620SIcenowy Zheng 341*7e4d5620SIcenowy Zheng return 0; 342*7e4d5620SIcenowy Zheng } 343*7e4d5620SIcenowy Zheng 344*7e4d5620SIcenowy Zheng static int mentor_i2c_data_transmit(uint8_t *p_block, uint32_t block_size) 345*7e4d5620SIcenowy Zheng { 346*7e4d5620SIcenowy Zheng uint32_t status, block_size_write = block_size; 347*7e4d5620SIcenowy Zheng 348*7e4d5620SIcenowy Zheng if (mentor_i2c_wait_interrupt()) { 349*7e4d5620SIcenowy Zheng ERROR("Start clear bit timeout\n"); 350*7e4d5620SIcenowy Zheng return -ETIMEDOUT; 351*7e4d5620SIcenowy Zheng } 352*7e4d5620SIcenowy Zheng 353*7e4d5620SIcenowy Zheng while (block_size_write) { 354*7e4d5620SIcenowy Zheng /* write the data */ 355*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->data, (uint32_t) *p_block); 356*7e4d5620SIcenowy Zheng VERBOSE("%s: index = %d, data = %x\n", __func__, 357*7e4d5620SIcenowy Zheng block_size - block_size_write, *p_block); 358*7e4d5620SIcenowy Zheng p_block++; 359*7e4d5620SIcenowy Zheng block_size_write--; 360*7e4d5620SIcenowy Zheng 361*7e4d5620SIcenowy Zheng mentor_i2c_interrupt_clear(); 362*7e4d5620SIcenowy Zheng 363*7e4d5620SIcenowy Zheng if (mentor_i2c_wait_interrupt()) { 364*7e4d5620SIcenowy Zheng ERROR("Start clear bit timeout\n"); 365*7e4d5620SIcenowy Zheng return -ETIMEDOUT; 366*7e4d5620SIcenowy Zheng } 367*7e4d5620SIcenowy Zheng 368*7e4d5620SIcenowy Zheng /* check the status */ 369*7e4d5620SIcenowy Zheng if (mentor_i2c_lost_arbitration(&status)) { 370*7e4d5620SIcenowy Zheng ERROR("%s - %d: Lost arbitration, got status %x\n", 371*7e4d5620SIcenowy Zheng __func__, __LINE__, status); 372*7e4d5620SIcenowy Zheng return -EAGAIN; 373*7e4d5620SIcenowy Zheng } 374*7e4d5620SIcenowy Zheng if (status != I2C_STATUS_DATA_W_ACK) { 375*7e4d5620SIcenowy Zheng ERROR("Status %x in write transaction\n", status); 376*7e4d5620SIcenowy Zheng return -EPERM; 377*7e4d5620SIcenowy Zheng } 378*7e4d5620SIcenowy Zheng } 379*7e4d5620SIcenowy Zheng 380*7e4d5620SIcenowy Zheng return 0; 381*7e4d5620SIcenowy Zheng } 382*7e4d5620SIcenowy Zheng 383*7e4d5620SIcenowy Zheng static int mentor_i2c_target_offset_set(uint8_t chip, uint32_t addr, int alen) 384*7e4d5620SIcenowy Zheng { 385*7e4d5620SIcenowy Zheng uint8_t off_block[2]; 386*7e4d5620SIcenowy Zheng uint32_t off_size; 387*7e4d5620SIcenowy Zheng 388*7e4d5620SIcenowy Zheng if (alen == 2) { /* 2-byte addresses support */ 389*7e4d5620SIcenowy Zheng off_block[0] = (addr >> 8) & 0xff; 390*7e4d5620SIcenowy Zheng off_block[1] = addr & 0xff; 391*7e4d5620SIcenowy Zheng off_size = 2; 392*7e4d5620SIcenowy Zheng } else { /* 1-byte addresses support */ 393*7e4d5620SIcenowy Zheng off_block[0] = addr & 0xff; 394*7e4d5620SIcenowy Zheng off_size = 1; 395*7e4d5620SIcenowy Zheng } 396*7e4d5620SIcenowy Zheng VERBOSE("%s: off_size = %x addr1 = %x addr2 = %x\n", __func__, 397*7e4d5620SIcenowy Zheng off_size, off_block[0], off_block[1]); 398*7e4d5620SIcenowy Zheng return mentor_i2c_data_transmit(off_block, off_size); 399*7e4d5620SIcenowy Zheng } 400*7e4d5620SIcenowy Zheng 401*7e4d5620SIcenowy Zheng #ifdef I2C_CAN_UNSTUCK 402*7e4d5620SIcenowy Zheng static int mentor_i2c_unstuck(int ret) 403*7e4d5620SIcenowy Zheng { 404*7e4d5620SIcenowy Zheng uint32_t v; 405*7e4d5620SIcenowy Zheng 406*7e4d5620SIcenowy Zheng if (ret != -ETIMEDOUT) 407*7e4d5620SIcenowy Zheng return ret; 408*7e4d5620SIcenowy Zheng VERBOSE("Trying to \"unstuck i2c\"... "); 409*7e4d5620SIcenowy Zheng i2c_init(base); 410*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->unstuck, I2C_UNSTUCK_TRIGGER); 411*7e4d5620SIcenowy Zheng do { 412*7e4d5620SIcenowy Zheng v = mmio_read_32((uintptr_t)&base->unstuck); 413*7e4d5620SIcenowy Zheng } while (v & I2C_UNSTUCK_ONGOING); 414*7e4d5620SIcenowy Zheng 415*7e4d5620SIcenowy Zheng if (v & I2C_UNSTUCK_ERROR) { 416*7e4d5620SIcenowy Zheng VERBOSE("failed - soft reset i2c\n"); 417*7e4d5620SIcenowy Zheng ret = -EPERM; 418*7e4d5620SIcenowy Zheng } else { 419*7e4d5620SIcenowy Zheng VERBOSE("ok\n"); 420*7e4d5620SIcenowy Zheng i2c_init(base); 421*7e4d5620SIcenowy Zheng ret = -EAGAIN; 422*7e4d5620SIcenowy Zheng } 423*7e4d5620SIcenowy Zheng return ret; 424*7e4d5620SIcenowy Zheng } 425*7e4d5620SIcenowy Zheng #else 426*7e4d5620SIcenowy Zheng static int mentor_i2c_unstuck(int ret) 427*7e4d5620SIcenowy Zheng { 428*7e4d5620SIcenowy Zheng VERBOSE("Cannot \"unstuck i2c\" - soft reset i2c\n"); 429*7e4d5620SIcenowy Zheng return -EPERM; 430*7e4d5620SIcenowy Zheng } 431*7e4d5620SIcenowy Zheng #endif 432*7e4d5620SIcenowy Zheng 433*7e4d5620SIcenowy Zheng /* 434*7e4d5620SIcenowy Zheng * API Functions 435*7e4d5620SIcenowy Zheng */ 436*7e4d5620SIcenowy Zheng void i2c_init(void *i2c_base) 437*7e4d5620SIcenowy Zheng { 438*7e4d5620SIcenowy Zheng /* For I2C speed and slave address, now we do not set them since 439*7e4d5620SIcenowy Zheng * we just provide the working speed and slave address otherwhere 440*7e4d5620SIcenowy Zheng * for i2c_init 441*7e4d5620SIcenowy Zheng */ 442*7e4d5620SIcenowy Zheng base = (struct mentor_i2c_regs *)i2c_base; 443*7e4d5620SIcenowy Zheng 444*7e4d5620SIcenowy Zheng /* Reset the I2C logic */ 445*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->soft_reset, 0); 446*7e4d5620SIcenowy Zheng 447*7e4d5620SIcenowy Zheng udelay(200); 448*7e4d5620SIcenowy Zheng 449*7e4d5620SIcenowy Zheng mentor_i2c_bus_speed_set(CONFIG_SYS_I2C_SPEED); 450*7e4d5620SIcenowy Zheng 451*7e4d5620SIcenowy Zheng /* Enable the I2C and slave */ 452*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->control, 453*7e4d5620SIcenowy Zheng I2C_CONTROL_TWSIEN | I2C_CONTROL_ACK); 454*7e4d5620SIcenowy Zheng 455*7e4d5620SIcenowy Zheng /* set the I2C slave address */ 456*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->xtnd_slave_addr, 0); 457*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->slave_address, CONFIG_SYS_I2C_SLAVE); 458*7e4d5620SIcenowy Zheng 459*7e4d5620SIcenowy Zheng /* unmask I2C interrupt */ 460*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->control, 461*7e4d5620SIcenowy Zheng mmio_read_32((uintptr_t)&base->control) | 462*7e4d5620SIcenowy Zheng I2C_CONTROL_INTEN); 463*7e4d5620SIcenowy Zheng 464*7e4d5620SIcenowy Zheng udelay(10); 465*7e4d5620SIcenowy Zheng } 466*7e4d5620SIcenowy Zheng 467*7e4d5620SIcenowy Zheng /* 468*7e4d5620SIcenowy Zheng * i2c_read: - Read multiple bytes from an i2c device 469*7e4d5620SIcenowy Zheng * 470*7e4d5620SIcenowy Zheng * The higher level routines take into account that this function is only 471*7e4d5620SIcenowy Zheng * called with len < page length of the device (see configuration file) 472*7e4d5620SIcenowy Zheng * 473*7e4d5620SIcenowy Zheng * @chip: address of the chip which is to be read 474*7e4d5620SIcenowy Zheng * @addr: i2c data address within the chip 475*7e4d5620SIcenowy Zheng * @alen: length of the i2c data address (1..2 bytes) 476*7e4d5620SIcenowy Zheng * @buffer: where to write the data 477*7e4d5620SIcenowy Zheng * @len: how much byte do we want to read 478*7e4d5620SIcenowy Zheng * @return: 0 in case of success 479*7e4d5620SIcenowy Zheng */ 480*7e4d5620SIcenowy Zheng int i2c_read(uint8_t chip, uint32_t addr, int alen, uint8_t *buffer, int len) 481*7e4d5620SIcenowy Zheng { 482*7e4d5620SIcenowy Zheng int ret = 0; 483*7e4d5620SIcenowy Zheng uint32_t counter = 0; 484*7e4d5620SIcenowy Zheng 485*7e4d5620SIcenowy Zheng #ifdef DEBUG_I2C 486*7e4d5620SIcenowy Zheng mentor_i2c_probe(chip); 487*7e4d5620SIcenowy Zheng #endif 488*7e4d5620SIcenowy Zheng 489*7e4d5620SIcenowy Zheng do { 490*7e4d5620SIcenowy Zheng if (ret != -EAGAIN && ret) { 491*7e4d5620SIcenowy Zheng ERROR("i2c transaction failed, after %d retries\n", 492*7e4d5620SIcenowy Zheng counter); 493*7e4d5620SIcenowy Zheng mentor_i2c_stop_bit_set(); 494*7e4d5620SIcenowy Zheng return ret; 495*7e4d5620SIcenowy Zheng } 496*7e4d5620SIcenowy Zheng 497*7e4d5620SIcenowy Zheng /* wait for 1 us for the interrupt clear to take effect */ 498*7e4d5620SIcenowy Zheng if (counter > 0) 499*7e4d5620SIcenowy Zheng udelay(1); 500*7e4d5620SIcenowy Zheng counter++; 501*7e4d5620SIcenowy Zheng 502*7e4d5620SIcenowy Zheng ret = mentor_i2c_start_bit_set(); 503*7e4d5620SIcenowy Zheng if (ret) { 504*7e4d5620SIcenowy Zheng ret = mentor_i2c_unstuck(ret); 505*7e4d5620SIcenowy Zheng continue; 506*7e4d5620SIcenowy Zheng } 507*7e4d5620SIcenowy Zheng 508*7e4d5620SIcenowy Zheng /* if EEPROM device */ 509*7e4d5620SIcenowy Zheng if (alen != 0) { 510*7e4d5620SIcenowy Zheng ret = mentor_i2c_address_set(chip, I2C_CMD_WRITE); 511*7e4d5620SIcenowy Zheng if (ret) 512*7e4d5620SIcenowy Zheng continue; 513*7e4d5620SIcenowy Zheng 514*7e4d5620SIcenowy Zheng ret = mentor_i2c_target_offset_set(chip, addr, alen); 515*7e4d5620SIcenowy Zheng if (ret) 516*7e4d5620SIcenowy Zheng continue; 517*7e4d5620SIcenowy Zheng ret = mentor_i2c_start_bit_set(); 518*7e4d5620SIcenowy Zheng if (ret) 519*7e4d5620SIcenowy Zheng continue; 520*7e4d5620SIcenowy Zheng } 521*7e4d5620SIcenowy Zheng 522*7e4d5620SIcenowy Zheng ret = mentor_i2c_address_set(chip, I2C_CMD_READ); 523*7e4d5620SIcenowy Zheng if (ret) 524*7e4d5620SIcenowy Zheng continue; 525*7e4d5620SIcenowy Zheng 526*7e4d5620SIcenowy Zheng ret = mentor_i2c_data_receive(buffer, len); 527*7e4d5620SIcenowy Zheng if (ret) 528*7e4d5620SIcenowy Zheng continue; 529*7e4d5620SIcenowy Zheng 530*7e4d5620SIcenowy Zheng ret = mentor_i2c_stop_bit_set(); 531*7e4d5620SIcenowy Zheng } while ((ret == -EAGAIN) && (counter < I2C_MAX_RETRY_CNT)); 532*7e4d5620SIcenowy Zheng 533*7e4d5620SIcenowy Zheng if (counter == I2C_MAX_RETRY_CNT) { 534*7e4d5620SIcenowy Zheng ERROR("I2C transactions failed, got EAGAIN %d times\n", 535*7e4d5620SIcenowy Zheng I2C_MAX_RETRY_CNT); 536*7e4d5620SIcenowy Zheng ret = -EPERM; 537*7e4d5620SIcenowy Zheng } 538*7e4d5620SIcenowy Zheng mmio_write_32((uintptr_t)&base->control, 539*7e4d5620SIcenowy Zheng mmio_read_32((uintptr_t)&base->control) | 540*7e4d5620SIcenowy Zheng I2C_CONTROL_ACK); 541*7e4d5620SIcenowy Zheng 542*7e4d5620SIcenowy Zheng udelay(1); 543*7e4d5620SIcenowy Zheng return ret; 544*7e4d5620SIcenowy Zheng } 545*7e4d5620SIcenowy Zheng 546*7e4d5620SIcenowy Zheng /* 547*7e4d5620SIcenowy Zheng * i2c_write: - Write multiple bytes to an i2c device 548*7e4d5620SIcenowy Zheng * 549*7e4d5620SIcenowy Zheng * The higher level routines take into account that this function is only 550*7e4d5620SIcenowy Zheng * called with len < page length of the device (see configuration file) 551*7e4d5620SIcenowy Zheng * 552*7e4d5620SIcenowy Zheng * @chip: address of the chip which is to be written 553*7e4d5620SIcenowy Zheng * @addr: i2c data address within the chip 554*7e4d5620SIcenowy Zheng * @alen: length of the i2c data address (1..2 bytes) 555*7e4d5620SIcenowy Zheng * @buffer: where to find the data to be written 556*7e4d5620SIcenowy Zheng * @len: how much byte do we want to read 557*7e4d5620SIcenowy Zheng * @return: 0 in case of success 558*7e4d5620SIcenowy Zheng */ 559*7e4d5620SIcenowy Zheng int i2c_write(uint8_t chip, uint32_t addr, int alen, uint8_t *buffer, int len) 560*7e4d5620SIcenowy Zheng { 561*7e4d5620SIcenowy Zheng int ret = 0; 562*7e4d5620SIcenowy Zheng uint32_t counter = 0; 563*7e4d5620SIcenowy Zheng 564*7e4d5620SIcenowy Zheng do { 565*7e4d5620SIcenowy Zheng if (ret != -EAGAIN && ret) { 566*7e4d5620SIcenowy Zheng ERROR("i2c transaction failed\n"); 567*7e4d5620SIcenowy Zheng mentor_i2c_stop_bit_set(); 568*7e4d5620SIcenowy Zheng return ret; 569*7e4d5620SIcenowy Zheng } 570*7e4d5620SIcenowy Zheng /* wait for 1 us for the interrupt clear to take effect */ 571*7e4d5620SIcenowy Zheng if (counter > 0) 572*7e4d5620SIcenowy Zheng udelay(1); 573*7e4d5620SIcenowy Zheng counter++; 574*7e4d5620SIcenowy Zheng 575*7e4d5620SIcenowy Zheng ret = mentor_i2c_start_bit_set(); 576*7e4d5620SIcenowy Zheng if (ret) { 577*7e4d5620SIcenowy Zheng ret = mentor_i2c_unstuck(ret); 578*7e4d5620SIcenowy Zheng continue; 579*7e4d5620SIcenowy Zheng } 580*7e4d5620SIcenowy Zheng 581*7e4d5620SIcenowy Zheng ret = mentor_i2c_address_set(chip, I2C_CMD_WRITE); 582*7e4d5620SIcenowy Zheng if (ret) 583*7e4d5620SIcenowy Zheng continue; 584*7e4d5620SIcenowy Zheng 585*7e4d5620SIcenowy Zheng /* if EEPROM device */ 586*7e4d5620SIcenowy Zheng if (alen != 0) { 587*7e4d5620SIcenowy Zheng ret = mentor_i2c_target_offset_set(chip, addr, alen); 588*7e4d5620SIcenowy Zheng if (ret) 589*7e4d5620SIcenowy Zheng continue; 590*7e4d5620SIcenowy Zheng } 591*7e4d5620SIcenowy Zheng 592*7e4d5620SIcenowy Zheng ret = mentor_i2c_data_transmit(buffer, len); 593*7e4d5620SIcenowy Zheng if (ret) 594*7e4d5620SIcenowy Zheng continue; 595*7e4d5620SIcenowy Zheng 596*7e4d5620SIcenowy Zheng ret = mentor_i2c_stop_bit_set(); 597*7e4d5620SIcenowy Zheng } while ((ret == -EAGAIN) && (counter < I2C_MAX_RETRY_CNT)); 598*7e4d5620SIcenowy Zheng 599*7e4d5620SIcenowy Zheng if (counter == I2C_MAX_RETRY_CNT) { 600*7e4d5620SIcenowy Zheng ERROR("I2C transactions failed, got EAGAIN %d times\n", 601*7e4d5620SIcenowy Zheng I2C_MAX_RETRY_CNT); 602*7e4d5620SIcenowy Zheng ret = -EPERM; 603*7e4d5620SIcenowy Zheng } 604*7e4d5620SIcenowy Zheng 605*7e4d5620SIcenowy Zheng udelay(1); 606*7e4d5620SIcenowy Zheng return ret; 607*7e4d5620SIcenowy Zheng } 608