coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
twsi.c File Reference
#include <console/console.h>
#include <soc/twsi.h>
#include <soc/clock.h>
#include <device/i2c.h>
#include <device/i2c_simple.h>
#include <delay.h>
#include <device/mmio.h>
#include <soc/addressmap.h>
#include <timer.h>
Include dependency graph for twsi.c:

Go to the source code of this file.

Data Structures

union  twsx_sw_twsi
 
union  twsx_sw_twsi_ext
 
union  twsx_int
 

Macros

#define TWSI_THP   24
 
#define TWSI_SW_TWSI   0x1000
 
#define TWSI_TWSI_SW   0x1008
 
#define TWSI_INT   0x1010
 
#define TWSI_SW_TWSI_EXT   0x1018
 
#define RST_BOOT_PNR_MUL(Val)   ((Val >> 33) & 0x1F)
 

Enumerations

enum  { TWSI_OP_WRITE = 0 , TWSI_OP_READ = 1 }
 
enum  { TWSI_EOP_SLAVE_ADDR = 0 , TWSI_EOP_CLK_CTL = 3 , TWSI_SW_EOP_IA = 6 }
 
enum  {
  TWSI_SLAVEADD = 0 , TWSI_DATA = 1 , TWSI_CTL = 2 , TWSI_CLKCTL = 3 ,
  TWSI_STAT = 3 , TWSI_SLAVEADD_EXT = 4 , TWSI_RST = 7
}
 
enum  {
  TWSI_CTL_AAK = (1 << 2) , TWSI_CTL_IFLG = (1 << 3) , TWSI_CTL_STP = (1 << 4) , TWSI_CTL_STA = (1 << 5) ,
  TWSI_CTL_ENAB = (1 << 6) , TWSI_CTL_CE = (1 << 7)
}
 
enum  {
  TWSI_STAT_BUS_ERROR = 0x00 , TWSI_STAT_START = 0x08 , TWSI_STAT_RSTART = 0x10 , TWSI_STAT_TXADDR_ACK = 0x18 ,
  TWSI_STAT_TXADDR_NAK = 0x20 , TWSI_STAT_TXDATA_ACK = 0x28 , TWSI_STAT_TXDATA_NAK = 0x30 , TWSI_STAT_TX_ARB_LOST = 0x38 ,
  TWSI_STAT_RXADDR_ACK = 0x40 , TWSI_STAT_RXADDR_NAK = 0x48 , TWSI_STAT_RXDATA_ACK_SENT = 0x50 , TWSI_STAT_RXDATA_NAK_SENT = 0x58 ,
  TWSI_STAT_SLAVE_RXADDR_ACK = 0x60 , TWSI_STAT_TX_ACK_ARB_LOST = 0x68 , TWSI_STAT_RX_GEN_ADDR_ACK = 0x70 , TWSI_STAT_RX_GEN_ADDR_ARB_LOST = 0x78 ,
  TWSI_STAT_SLAVE_RXDATA_ACK = 0x80 , TWSI_STAT_SLAVE_RXDATA_NAK = 0x88 , TWSI_STAT_GEN_RXADDR_ACK = 0x90 , TWSI_STAT_GEN_RXADDR_NAK = 0x98 ,
  TWSI_STAT_STOP_MULTI_START = 0xA0 , TWSI_STAT_SLAVE_RXADDR2_ACK = 0xA8 , TWSI_STAT_RXDATA_ACK_ARB_LOST = 0xB0 , TWSI_STAT_SLAVE_TXDATA_ACK = 0xB8 ,
  TWSI_STAT_SLAVE_TXDATA_NAK = 0xC0 , TWSI_STAT_SLAVE_TXDATA_END_ACK = 0xC8 , TWSI_STAT_TXADDR2DATA_ACK = 0xD0 , TWSI_STAT_TXADDR2DATA_NAK = 0xD8 ,
  TWSI_STAT_IDLE = 0xF8
}
 

Functions

static int twsi_i2c_lost_arb (u8 code, int final_read)
 Returns true if we lost arbitration. More...
 
static u64 twsi_write_sw (void *baseaddr, union twsx_sw_twsi sw_twsi)
 Writes to the MIO_TWS(0..5)_SW_TWSI register. More...
 
static u64 twsi_read_sw (void *baseaddr, union twsx_sw_twsi sw_twsi)
 Reads the MIO_TWS(0..5)_SW_TWSI register. More...
 
static void twsi_write_ctl (void *baseaddr, const u8 data)
 Write control register. More...
 
static u32 twsi_read_ctl (void *baseaddr)
 Reads the TWSI Control Register. More...
 
static u8 twsi_read_status (void *baseaddr)
 Read i2c status register. More...
 
static int twsi_wait (void *baseaddr, struct stopwatch *timeout)
 Waits for an i2c operation to complete. More...
 
static int twsi_stop (void *baseaddr)
 Sends an i2c stop condition. More...
 
static void twsi_unblock (void *baseaddr)
 Manually clear the I2C bus and send a stop. More...
 
static int twsi_start_unstick (void *baseaddr)
 Unsticks the i2c bus. More...
 
static int twsi_start (void *baseaddr)
 Sends an i2c start condition. More...
 
static int twsi_write_data (void *baseaddr, const u8 slave_addr, const u8 *buffer, const unsigned int length)
 Writes data to the i2c bus. More...
 
static int twsi_read_data (void *baseaddr, const u8 slave_addr, u8 *buffer, const unsigned int length)
 Performs a read transaction on the i2c bus. More...
 
static int twsi_set_speed (void *baseaddr, const unsigned int speed)
 
int twsi_init (unsigned int bus, enum i2c_speed hz)
 
int platform_i2c_transfer (unsigned int bus, struct i2c_msg *segments, int seg_count)
 

Macro Definition Documentation

◆ RST_BOOT_PNR_MUL

#define RST_BOOT_PNR_MUL (   Val)    ((Val >> 33) & 0x1F)

Definition at line 228 of file twsi.c.

◆ TWSI_INT

#define TWSI_INT   0x1010

Definition at line 21 of file twsi.c.

◆ TWSI_SW_TWSI

#define TWSI_SW_TWSI   0x1000

Definition at line 19 of file twsi.c.

◆ TWSI_SW_TWSI_EXT

#define TWSI_SW_TWSI_EXT   0x1018

Definition at line 22 of file twsi.c.

◆ TWSI_THP

#define TWSI_THP   24

Definition at line 17 of file twsi.c.

◆ TWSI_TWSI_SW

#define TWSI_TWSI_SW   0x1008

Definition at line 20 of file twsi.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
TWSI_OP_WRITE 
TWSI_OP_READ 

Definition at line 66 of file twsi.c.

◆ anonymous enum

anonymous enum
Enumerator
TWSI_EOP_SLAVE_ADDR 
TWSI_EOP_CLK_CTL 
TWSI_SW_EOP_IA 

Definition at line 71 of file twsi.c.

◆ anonymous enum

anonymous enum
Enumerator
TWSI_SLAVEADD 
TWSI_DATA 
TWSI_CTL 
TWSI_CLKCTL 
TWSI_STAT 
TWSI_SLAVEADD_EXT 
TWSI_RST 

Definition at line 77 of file twsi.c.

◆ anonymous enum

anonymous enum
Enumerator
TWSI_CTL_AAK 
TWSI_CTL_IFLG 
TWSI_CTL_STP 
TWSI_CTL_STA 
TWSI_CTL_ENAB 
TWSI_CTL_CE 

Definition at line 87 of file twsi.c.

◆ anonymous enum

anonymous enum
Enumerator
TWSI_STAT_BUS_ERROR 

Bus error.

TWSI_STAT_START 

Start condition transmitted.

TWSI_STAT_RSTART 

Repeat start condition transmitted.

TWSI_STAT_TXADDR_ACK 

Address + write bit transmitted, ACK received.

TWSI_STAT_TXADDR_NAK 

Address + write bit transmitted, /ACK received.

TWSI_STAT_TXDATA_ACK 

Data byte transmitted in master mode, ACK received.

TWSI_STAT_TXDATA_NAK 

Data byte transmitted in master mode, ACK received.

TWSI_STAT_TX_ARB_LOST 

Arbitration lost in address or data byte.

TWSI_STAT_RXADDR_ACK 

Address + read bit transmitted, ACK received.

TWSI_STAT_RXADDR_NAK 

Address + read bit transmitted, /ACK received.

TWSI_STAT_RXDATA_ACK_SENT 

Data byte received in master mode, ACK transmitted.

TWSI_STAT_RXDATA_NAK_SENT 

Data byte received, NACK transmitted.

TWSI_STAT_SLAVE_RXADDR_ACK 

Slave address received, sent ACK.

TWSI_STAT_TX_ACK_ARB_LOST 

Arbitration lost in address as master, slave address + write bit received, ACK transmitted.

TWSI_STAT_RX_GEN_ADDR_ACK 

General call address received, ACK transmitted.

TWSI_STAT_RX_GEN_ADDR_ARB_LOST 

Arbitration lost in address as master, general call address received, ACK transmitted.

TWSI_STAT_SLAVE_RXDATA_ACK 

Data byte received after slave address received, ACK transmitted.

TWSI_STAT_SLAVE_RXDATA_NAK 

Data byte received after slave address received, /ACK transmitted.

TWSI_STAT_GEN_RXADDR_ACK 

Data byte received after general call address received, ACK transmitted.

TWSI_STAT_GEN_RXADDR_NAK 

Data byte received after general call address received, /ACK transmitted.

TWSI_STAT_STOP_MULTI_START 

STOP or repeated START condition received in slave mode.

TWSI_STAT_SLAVE_RXADDR2_ACK 

Slave address + read bit received, ACK transmitted.

TWSI_STAT_RXDATA_ACK_ARB_LOST 

Arbitration lost in address as master, slave address + read bit received, ACK transmitted.

TWSI_STAT_SLAVE_TXDATA_ACK 

Data byte transmitted in slave mode, ACK received.

TWSI_STAT_SLAVE_TXDATA_NAK 

Data byte transmitted in slave mode, /ACK received.

TWSI_STAT_SLAVE_TXDATA_END_ACK 

Last byte transmitted in slave mode, ACK received.

TWSI_STAT_TXADDR2DATA_ACK 

Second address byte + write bit transmitted, ACK received.

TWSI_STAT_TXADDR2DATA_NAK 

Second address byte + write bit transmitted, /ACK received.

TWSI_STAT_IDLE 

No relevant status information.

Definition at line 96 of file twsi.c.

Function Documentation

◆ platform_i2c_transfer()

int platform_i2c_transfer ( unsigned int  bus,
struct i2c_msg segments,
int  seg_count 
)

Definition at line 664 of file twsi.c.

References BIOS_ERR, BIOS_SPEW, i2c_msg::buf, i2c_msg::flags, I2C_M_RD, i2c_msg::len, MIO_TWSx_PF_BAR0, printk, i2c_msg::slave, twsi_read_data(), and twsi_write_data().

Here is the call graph for this function:

◆ twsi_i2c_lost_arb()

static int twsi_i2c_lost_arb ( u8  code,
int  final_read 
)
static

◆ twsi_init()

int twsi_init ( unsigned int  bus,
enum i2c_speed  hz 
)

Definition at line 649 of file twsi.c.

References MIO_TWSx_PF_BAR0, TWSI_CTL_ENAB, twsi_set_speed(), and twsi_write_ctl().

Referenced by mainboard_enable().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ twsi_read_ctl()

static u32 twsi_read_ctl ( void baseaddr)
static

Reads the TWSI Control Register.

Parameters
[in]baseaddrBase address for i2c
Returns
8-bit TWSI control register

Definition at line 314 of file twsi.c.

References BIOS_SPEW, twsx_sw_twsi::data, twsx_sw_twsi::eop_ia, twsx_sw_twsi::op, printk, twsx_sw_twsi::s, TWSI_CTL, twsi_read_sw(), TWSI_SW_EOP_IA, and twsx_sw_twsi::u.

Referenced by twsi_wait().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ twsi_read_data()

static int twsi_read_data ( void baseaddr,
const u8  slave_addr,
u8 buffer,
const unsigned int  length 
)
static

Performs a read transaction on the i2c bus.

Parameters
baseaddrBase address of twsi registers
slave_addri2c bus address to read from
bufferbuffer to read into
lengthnumber of bytes to read
Returns
0 for success, otherwise error

Definition at line 549 of file twsi.c.

References BIOS_ERR, BIOS_SPEW, buffer, twsx_sw_twsi::data, twsx_sw_twsi::eop_ia, length, twsx_sw_twsi::op, printk, twsx_sw_twsi::s, stopwatch_init_usecs_expire(), TWSI_CTL_AAK, TWSI_CTL_ENAB, TWSI_DATA, twsi_i2c_lost_arb(), TWSI_OP_READ, twsi_read_status(), twsi_read_sw(), twsi_start(), TWSI_STAT_RXADDR_ACK, twsi_stop(), TWSI_SW_EOP_IA, twsi_wait(), twsi_write_ctl(), twsi_write_sw(), and twsx_sw_twsi::u.

Referenced by platform_i2c_transfer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ twsi_read_status()

static u8 twsi_read_status ( void baseaddr)
static

Read i2c status register.

Parameters
baseaddrBase address of i2c registers
Returns
value of status register

Definition at line 334 of file twsi.c.

References twsx_sw_twsi::eop_ia, twsx_sw_twsi::op, twsx_sw_twsi::s, twsi_read_sw(), TWSI_STAT, TWSI_SW_EOP_IA, and twsx_sw_twsi::u.

Referenced by twsi_read_data(), twsi_start(), twsi_stop(), and twsi_write_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ twsi_read_sw()

static u64 twsi_read_sw ( void baseaddr,
union twsx_sw_twsi  sw_twsi 
)
static

Reads the MIO_TWS(0..5)_SW_TWSI register.

Parameters
baseaddrBase address of i2c registers
sw_twsivalue for eia and op, etc. to read
Returns
value of the register

Definition at line 265 of file twsi.c.

References BIOS_ERR, BIOS_SPEW, printk, twsx_sw_twsi::r, read64(), twsx_sw_twsi::s, TWSI_SW_TWSI, twsx_sw_twsi::u, twsx_sw_twsi::v, and write64().

Referenced by twsi_read_ctl(), twsi_read_data(), and twsi_read_status().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ twsi_set_speed()

static int twsi_set_speed ( void baseaddr,
const unsigned int  speed 
)
static

Definition at line 614 of file twsi.c.

References twsx_sw_twsi::data, twsx_sw_twsi::eop_ia, twsx_sw_twsi::op, twsx_sw_twsi::r, twsx_sw_twsi::s, thunderx_get_io_clock(), TWSI_THP, twsi_write_sw(), twsx_sw_twsi::u, and twsx_sw_twsi::v.

Referenced by twsi_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ twsi_start()

static int twsi_start ( void baseaddr)
static

Sends an i2c start condition.

Parameters
baseaddrbase address of registers
Returns
0 for success, otherwise error

Definition at line 436 of file twsi.c.

References BIOS_SPEW, printk, stopwatch_init_usecs_expire(), TWSI_CTL_ENAB, TWSI_CTL_STA, twsi_read_status(), twsi_start_unstick(), TWSI_STAT_RSTART, TWSI_STAT_RXADDR_ACK, TWSI_STAT_START, twsi_wait(), and twsi_write_ctl().

Referenced by twsi_read_data(), and twsi_write_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ twsi_start_unstick()

static int twsi_start_unstick ( void baseaddr)
static

Unsticks the i2c bus.

Parameters
baseaddrbase address of registers

Definition at line 420 of file twsi.c.

References twsi_stop(), and twsi_unblock().

Referenced by twsi_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ twsi_stop()

static int twsi_stop ( void baseaddr)
static

Sends an i2c stop condition.

Parameters
baseaddrregister base address
Returns
0 for success, -1 if error

Definition at line 373 of file twsi.c.

References BIOS_ERR, printk, TWSI_CTL_ENAB, TWSI_CTL_STP, twsi_read_status(), TWSI_STAT_IDLE, and twsi_write_ctl().

Referenced by twsi_read_data(), twsi_start_unstick(), and twsi_write_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ twsi_unblock()

static void twsi_unblock ( void baseaddr)
static

Manually clear the I2C bus and send a stop.

Definition at line 390 of file twsi.c.

References twsx_int::s, twsx_int::scl_ovr, twsx_int::sda_ovr, TWSI_INT, twsx_int::u, udelay(), and write64().

Referenced by twsi_start_unstick().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ twsi_wait()

static int twsi_wait ( void baseaddr,
struct stopwatch timeout 
)
static

Waits for an i2c operation to complete.

Parameters
baseaddrBase address of registers
Returns
0 for success, 1 if timeout

Definition at line 352 of file twsi.c.

References BIOS_SPEW, printk, stopwatch_expired(), TWSI_CTL_IFLG, and twsi_read_ctl().

Referenced by twsi_read_data(), twsi_start(), and twsi_write_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ twsi_write_ctl()

static void twsi_write_ctl ( void baseaddr,
const u8  data 
)
static

Write control register.

Parameters
baseaddrBase address for i2c registers
datadata to write

Definition at line 293 of file twsi.c.

References BIOS_SPEW, twsx_sw_twsi::data, twsx_sw_twsi::eop_ia, twsx_sw_twsi::op, printk, twsx_sw_twsi::s, TWSI_CTL, TWSI_SW_EOP_IA, twsi_write_sw(), and twsx_sw_twsi::u.

Referenced by twsi_init(), twsi_read_data(), twsi_start(), twsi_stop(), and twsi_write_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ twsi_write_data()

static int twsi_write_data ( void baseaddr,
const u8  slave_addr,
const u8 buffer,
const unsigned int  length 
)
static

Writes data to the i2c bus.

Parameters
baseraddrregister base address
slave_addraddress of slave to write to
bufferPointer to buffer to write
lengthNumber of bytes in buffer to write
Returns
0 for success, otherwise error

Definition at line 473 of file twsi.c.

References BIOS_ERR, BIOS_SPEW, buffer, twsx_sw_twsi::data, twsx_sw_twsi::eop_ia, length, twsx_sw_twsi::op, printk, twsx_sw_twsi::s, stopwatch_init_usecs_expire(), TWSI_CTL_ENAB, TWSI_DATA, twsi_i2c_lost_arb(), TWSI_OP_WRITE, twsi_read_status(), twsi_start(), TWSI_STAT_TXADDR_ACK, twsi_stop(), TWSI_SW_EOP_IA, twsi_wait(), twsi_write_ctl(), twsi_write_sw(), and twsx_sw_twsi::u.

Referenced by platform_i2c_transfer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ twsi_write_sw()

static u64 twsi_write_sw ( void baseaddr,
union twsx_sw_twsi  sw_twsi 
)
static

Writes to the MIO_TWS(0..5)_SW_TWSI register.

Parameters
baseaddrBase address of i2c registers
sw_twsivalue to write
Returns
0 for success, otherwise error

Definition at line 238 of file twsi.c.

References BIOS_ERR, BIOS_SPEW, printk, twsx_sw_twsi::r, read64(), twsx_sw_twsi::s, TWSI_SW_TWSI, twsx_sw_twsi::u, twsx_sw_twsi::v, and write64().

Referenced by twsi_read_data(), twsi_set_speed(), twsi_write_ctl(), and twsi_write_data().

Here is the call graph for this function:
Here is the caller graph for this function: