summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Geddes <crgeddes@us.ibm.com>2018-12-07 13:46:59 -0600
committerSachin Gupta <sgupta2m@in.ibm.com>2019-02-12 22:39:26 -0600
commit0f9a51d0059ecf66951a0d07fb43f0e10094277d (patch)
tree35d76bcf1d7b12fbe9f8404d3fba1c2e953719ce
parent9eba57570f299b3844bc6b7636d8088d879271a4 (diff)
downloadtalos-sbe-0f9a51d0059ecf66951a0d07fb43f0e10094277d.tar.gz
talos-sbe-0f9a51d0059ecf66951a0d07fb43f0e10094277d.zip
Update i2c driver for OCMB chip
After doing some testing with the simics Axone model we found that we had some errors in the protocols used to do reg reads and writes. We had to put extra dummy information when we latch and address to read and also we were not reading enough bytes when reading the status. This commit addresses both of these issues. Change-Id: I15ce40ef28d6c6c2303fe600986c8872b0829ad0 RTC: 196806 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/69575 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/71414 Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
-rw-r--r--src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H66
1 files changed, 40 insertions, 26 deletions
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H
index 4951a7f2..2afce077 100644
--- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H
+++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER sbe Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2018 */
+/* Contributors Listed Below - COPYRIGHT 2018,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -114,6 +114,8 @@ inline fapi2::ReturnCode fw_status(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_C
{
std::vector<uint8_t> l_data;
FAPI_TRY(fapi2::getI2c(i_target, l_size, l_cmd_id, l_data));
+ FAPI_INF( "status returned ( 5 bytes ) : 0x%.02X 0x%.02X 0x%.02X 0x%.02X 0x%.02X",
+ l_data[0], l_data[1] , l_data[2], l_data[3], l_data[4]);
FAPI_TRY( check::status_code(i_target, l_cmd_id[0], l_data) );
}
@@ -197,12 +199,9 @@ inline fapi2::ReturnCode fw_reg_write(const fapi2::Target<fapi2::TARGET_TYPE_OC
{
// create byte vector that will hold command bytes in sequence that will do the scom
std::vector<uint8_t> l_cmd_vector;
- std::vector<uint8_t> l_le_addr_vector;
- std::vector<uint8_t> l_le_data_vector;
- uint32_t l_input_data = static_cast<uint32_t>(i_data_buffer);
+ std::vector<uint8_t> l_be_vector;
- forceLE(i_addr, l_le_addr_vector);
- forceLE(l_input_data, l_le_data_vector);
+ uint32_t l_input_data = static_cast<uint32_t>(i_data_buffer);
// Start building the cmd vector for the write operation
l_cmd_vector.push_back(FW_REG_WRITE); // Byte 0 = 0x05 (FW_REG_WRITE)
@@ -212,9 +211,14 @@ inline fapi2::ReturnCode fw_reg_write(const fapi2::Target<fapi2::TARGET_TYPE_OC
// write them directly to the cmd_vector in the same order they
// currently are
// Byte 2:5 = Address
- l_cmd_vector.insert(l_cmd_vector.end(), l_le_addr_vector.begin(), l_le_addr_vector.end());
+ forceBE(i_addr, l_be_vector);
+ l_cmd_vector.insert(l_cmd_vector.end(), l_be_vector.begin(), l_be_vector.end());
+
+ l_be_vector.clear();
+ forceBE(l_input_data, l_be_vector);
+
// Byte 6:9 = Data
- l_cmd_vector.insert(l_cmd_vector.end(), l_le_data_vector.begin(), l_le_data_vector.end());
+ l_cmd_vector.insert(l_cmd_vector.end(), l_be_vector.begin(), l_be_vector.end());
// Use fapi2 putI2c interface to execute command
FAPI_TRY(fapi2::putI2c(i_target, l_cmd_vector),
@@ -244,22 +248,23 @@ inline fapi2::ReturnCode fw_reg_read(const fapi2::Target<fapi2::TARGET_TYPE_OCMB
{
// create byte vector that will hold command bytes in sequence that will do the scom
std::vector<uint8_t> l_cmd_vector;
- std::vector<uint8_t> l_read_data;
- std::vector<uint8_t> l_le_addr_vector;
- uint32_t l_index = 0;
- uint32_t l_read_value = 0;
+ std::vector<uint8_t> l_tmp_vector;
- forceLE(i_addr, l_le_addr_vector);
+ // Flush o_data_buffer w/ all 0's to avoid stale data
+ o_data_buffer.flush<0>();
+
+ // Force the address to be BE
+ forceBE(i_addr, l_tmp_vector);
// Build the cmd vector for the Read
l_cmd_vector.push_back(FW_REG_ADDR_LATCH); // Byte 0 = 0x03 (FW_REG_ADDR_LATCH)
l_cmd_vector.push_back(FW_REG_ADDR_LATCH_SIZE); // Byte 1 = 0x04 (FW_REG_ADDR_LATCH_SIZE)
- // i_addr was converted to LE above so we can write it
+ // i_addr was converted to BE above so we can write it
// directly to the cmd_vector in the same order it
// currently is in
// Byte 2:5 = Address
- l_cmd_vector.insert(l_cmd_vector.end(), l_le_addr_vector.begin(), l_le_addr_vector.end());
+ l_cmd_vector.insert(l_cmd_vector.end(), l_tmp_vector.begin(), l_tmp_vector.end());
// Use fapi2 putI2c interface to execute command
FAPI_TRY(fapi2::putI2c(i_target, l_cmd_vector),
@@ -271,41 +276,50 @@ inline fapi2::ReturnCode fw_reg_read(const fapi2::Target<fapi2::TARGET_TYPE_OCMB
"Invalid Status after FW_REG_ADDR_LATCH operation to 0x%.8X on OCMB w/ fapiPos = 0x%.8X",
i_addr, mss::fapi_pos(i_target));
+ // Clear out the tmp_vector because we will re-use as the read buffer
+ l_tmp_vector.clear();
+
// Clear out cmd vector as i2c op is complete and we must prepare for next
l_cmd_vector.clear();
// Cmd vector is a single byte with FW_REG_READ code
l_cmd_vector.push_back(FW_REG_READ); // Byte 0 = 0x04 (FW_REG_READ)
+ l_cmd_vector.push_back(0x4); // Remaining bytes dont matter to HB firmware
+ l_cmd_vector.push_back(0x0); // but the hw is expecting something there so
+ l_cmd_vector.push_back(0x0); // we should write something
+ l_cmd_vector.push_back(0x0);
+ l_cmd_vector.push_back(0x0);
// Use fapi2 getI2c interface to execute command
- FAPI_TRY(fapi2::getI2c(i_target, FW_I2C_SCOM_READ_SIZE, l_cmd_vector, l_read_data),
+ FAPI_TRY(fapi2::getI2c(i_target, FW_I2C_SCOM_READ_SIZE, l_cmd_vector, l_tmp_vector),
"getI2c returned error for FW_REG_READ operation to 0x%.8X on OCMB w/ fapiPos = 0x%.8X",
i_addr, mss::fapi_pos(i_target));
// The first byte returned should be the size of the remaining data
// We requested FW_REG_ADDR_LATCH_SIZE bytes so that is what we
// expect to see as the first byte.
- FAPI_ASSERT( (l_read_data.front() == FW_REG_ADDR_LATCH_SIZE),
+ FAPI_ASSERT( (l_tmp_vector.front() == FW_REG_ADDR_LATCH_SIZE),
fapi2::I2C_GET_SCOM_INVALID_READ_SIZE()
.set_TARGET(i_target)
.set_ADDRESS(i_addr)
- .set_SIZE_RETURNED(l_read_data[0])
+ .set_SIZE_RETURNED(l_tmp_vector[0])
.set_SIZE_REQUESTED(FW_REG_ADDR_LATCH_SIZE),
"First byte of read data was expected to be 0x%lx but byte read = 0x%x",
- FW_REG_ADDR_LATCH_SIZE, l_read_data[0] );
+ FW_REG_ADDR_LATCH_SIZE, l_tmp_vector[0] );
// Check i2c status after operation
FAPI_TRY(fw_status(i_target),
"Invalid Status after FW_REG_READ operation to 0x%.8X on OCMB w/ fapiPos = 0x%.8X",
i_addr, mss::fapi_pos(i_target));
- // The OCMB is a 32-bit little endian engine so
- // we must convert the buffer that we read into native
- // incase native endian is different than LE
- readLE(l_read_data, l_index, l_read_value);
- o_data_buffer = l_read_value;
-
-
+ // Build uint32_t from bytes 1-4 of the returned data. Bytes are
+ // returned in BE so no translation neccesary. Faster to just access
+ // the 4 bytes and shift than to perform vector operations to pop off front
+ // entry and convert vector to uint32.
+ o_data_buffer = ( l_tmp_vector[1] << 24 |
+ l_tmp_vector[2] << 16 |
+ l_tmp_vector[3] << 8 |
+ l_tmp_vector[4]);
fapi_try_exit:
return fapi2::current_err;
}
OpenPOWER on IntegriCloud