southbridge/intel/common/smbus: Add do_i2c_block_write()
Intel Braswell supports i2c block writes using SMBus controller. This support is missing in actual smbus routines. Add do_i2c_block_write() which is a based on do_smbus_block_write() but also write first byte to SMBHSTDAT1. The caller needs to configure the SMBus controller in i2c mode. In i2c mode SMBus controller will send the next sequence: SMBXINTADD, SMBHSTDAT1, SMBBLKDAT .. SMBBLKDAT To ensure the the command is send over the bus the SMBHSTCMD register must be written also BUG=N/A TEST=Config eDP for LCD display on Facebook FBG-1701 Change-Id: I40f8c0f5257a62398189f36892b8159052481693 Signed-off-by: Frans Hendriks <fhendriks@eltan.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/30800 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
This commit is contained in:
parent
b09de70eda
commit
e48be35bca
|
@ -4,6 +4,7 @@
|
||||||
* Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
|
* Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
|
||||||
* Copyright (C) 2009 coresystems GmbH
|
* Copyright (C) 2009 coresystems GmbH
|
||||||
* Copyright (C) 2013 Vladimir Serbinenko
|
* Copyright (C) 2013 Vladimir Serbinenko
|
||||||
|
* Copyright (C) 2018-2019 Eltan B.V.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -410,3 +411,47 @@ int do_i2c_eeprom_read(unsigned int smbus_base, u8 device,
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The caller is responsible of settings HOSTC I2C_EN bit prior to making this
|
||||||
|
* call!
|
||||||
|
*/
|
||||||
|
int do_i2c_block_write(unsigned int smbus_base, u8 device,
|
||||||
|
unsigned int bytes, u8 *buf)
|
||||||
|
{
|
||||||
|
u8 cmd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!CONFIG(SOC_INTEL_BRASWELL))
|
||||||
|
return SMBUS_ERROR;
|
||||||
|
|
||||||
|
if (!bytes || (bytes > SMBUS_BLOCK_MAXLEN))
|
||||||
|
return SMBUS_ERROR;
|
||||||
|
|
||||||
|
/* Set up for a block data write. */
|
||||||
|
ret = setup_command(smbus_base, I801_BLOCK_DATA, XMIT_WRITE(device));
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In i2c mode SMBus controller sequence on bus will be:
|
||||||
|
* <SMBXINTADD> <SMBHSTDAT1> <SMBBLKDAT> .. <SMBBLKDAT>
|
||||||
|
* The SMBHSTCMD must be written also to ensure the SMBUs controller
|
||||||
|
* will generate the i2c sequence.
|
||||||
|
*/
|
||||||
|
cmd = *buf++;
|
||||||
|
bytes--;
|
||||||
|
outb(cmd, smbus_base + SMBHSTCMD);
|
||||||
|
outb(cmd, smbus_base + SMBHSTDAT1);
|
||||||
|
|
||||||
|
/* Execute block transaction. */
|
||||||
|
ret = block_cmd_loop(smbus_base, buf, bytes, BLOCK_WRITE);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (ret < bytes)
|
||||||
|
return SMBUS_ERROR;
|
||||||
|
|
||||||
|
ret++; /* 1st byte has been written using SMBHSTDAT1 */
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -43,4 +43,6 @@ int do_smbus_block_write(unsigned int smbus_base, u8 device,
|
||||||
/* Only since ICH5 */
|
/* Only since ICH5 */
|
||||||
int do_i2c_eeprom_read(unsigned int smbus_base, u8 device,
|
int do_i2c_eeprom_read(unsigned int smbus_base, u8 device,
|
||||||
unsigned int offset, unsigned int bytes, u8 *buf);
|
unsigned int offset, unsigned int bytes, u8 *buf);
|
||||||
|
int do_i2c_block_write(unsigned int smbus_base, u8 device,
|
||||||
|
unsigned int bytes, u8 *buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue