southbridge/intel/common: Add Process Call
Add functionality to use process call cycle. It can be used to write/read data to/from e.g. EEPROM attached to SMBus Controller via I2C. Tested on: * C246 Change-Id: Ifdac6cf70a4ce744601f5d152a83d2125ea88360 Signed-off-by: Christian Walter <christian.walter@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/39875 Reviewed-by: Patrick Rudolph <siro@das-labor.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
5cb34e2ea0
commit
04953ebf5f
|
@ -17,6 +17,7 @@ int do_smbus_write_word(uintptr_t base, u8 device, u8 address, u16 data);
|
|||
|
||||
int do_smbus_block_read(uintptr_t base, u8 device, u8 cmd, size_t max_bytes, u8 *buf);
|
||||
int do_smbus_block_write(uintptr_t base, u8 device, u8 cmd, size_t bytes, const u8 *buf);
|
||||
int do_smbus_process_call(uintptr_t base, u8 device, u8 cmd, u16 data, u16 *buf);
|
||||
|
||||
/* For Intel, implemented since ICH5. */
|
||||
int do_i2c_eeprom_read(uintptr_t base, u8 device, u8 offset, size_t bytes, u8 *buf);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#define I801_BYTE (1 << 2)
|
||||
#define I801_BYTE_DATA (2 << 2)
|
||||
#define I801_WORD_DATA (3 << 2)
|
||||
#define I801_PROCESS_CALL (4 << 2)
|
||||
#define I801_BLOCK_DATA (5 << 2)
|
||||
#define I801_I2C_BLOCK_DATA (6 << 2) /* ICH5 and later */
|
||||
|
||||
|
@ -391,6 +392,42 @@ int do_smbus_block_read(uintptr_t base, u8 device, u8 cmd, size_t max_bytes, u8
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller is responsible of settings HOSTC I2C_EN bit prior to making this
|
||||
* call!
|
||||
*/
|
||||
int do_smbus_process_call(uintptr_t base, u8 device, u8 cmd, u16 data, u16 *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Set up for process call */
|
||||
ret = setup_command(base, I801_PROCESS_CALL, XMIT_WRITE(device));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* cmd will only be send if I2C_EN is zero */
|
||||
host_outb(base, SMBHSTCMD, cmd);
|
||||
|
||||
host_outb(base, SMBHSTDAT0, data & 0x00ff);
|
||||
host_outb(base, SMBHSTDAT1, (data & 0xff00) >> 8);
|
||||
|
||||
/* Start the command */
|
||||
ret = execute_command(base);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Poll for transaction completion */
|
||||
ret = complete_command(base);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Read results of transaction */
|
||||
*buf = host_inb(base, SMBHSTDAT0);
|
||||
*buf |= (host_inb(base, SMBHSTDAT1) << 8);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int do_smbus_block_write(uintptr_t base, u8 device, u8 cmd, const size_t bytes, const u8 *buf)
|
||||
{
|
||||
int ret;
|
||||
|
|
Loading…
Reference in New Issue