summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoachim Fenkes <fenkes@de.ibm.com>2017-08-09 15:36:46 +0200
committerChristian R. Geddes <crgeddes@us.ibm.com>2019-02-12 16:47:18 -0600
commit05f19a490fbedee4db73c1c5cde40ab14bd51802 (patch)
tree116ab744b40c32b59b97eca374e718af5d846c26
parent40451eef027e197fec3e8f092ec851e63c00e84c (diff)
downloadtalos-hostboot-05f19a490fbedee4db73c1c5cde40ab14bd51802.tar.gz
talos-hostboot-05f19a490fbedee4db73c1c5cde40ab14bd51802.zip
p9_sbe_lpc_init: Fix LPC bus LRESET for DD2
Change the order of operations so that first the LPC Master is reset, then the bus reset is driven with a proper delay. Previously the bus reset duration depended on the code path taken (DD1 vs. DD2) and was likely too short on DD2. Also extract the various parts of the sequence into individual functions to improve readability. Change-Id: I55cd750735ae21131c57c185ffc8a4fa1392b2dc Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/44416 Reviewed-by: Dean Sanner <dsanner@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com> Reviewed-by: Joseph J. McGill <jmcgill@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/71479 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_sbe_lpc_init.C174
-rw-r--r--src/import/chips/p9/procedures/hwp/perv/p9_sbe_lpc_init.H1
2 files changed, 111 insertions, 64 deletions
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_lpc_init.C b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_lpc_init.C
index b1fdd84a1..689478f26 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_lpc_init.C
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_lpc_init.C
@@ -44,65 +44,13 @@
#include "p9_misc_scom_addresses.H"
#include "p9_misc_scom_addresses_fld.H"
-fapi2::ReturnCode p9_sbe_lpc_init(const
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target_chip)
+static fapi2::ReturnCode reset_lpc_master(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target_chip)
{
- const uint64_t C_LPC_TIMEOUT_ADDR = 0x00400000C001202C;
- const uint64_t C_LPC_TIMEOUT_DATA = 0x00000000FE000000;
- const uint64_t C_OPB_TIMEOUT_ADDR = 0x00400000C0010040;
- const uint64_t C_OPB_TIMEOUT_DATA = 0x00000000FFFFFFFE;
fapi2::buffer<uint64_t> l_data64;
- uint8_t l_use_gpio = 0;
- uint8_t l_is_fsp = 0;
- FAPI_DBG("p9_sbe_lpc_init: Entering ...");
-
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_LPC_RESET_GPIO, i_target_chip, l_use_gpio),
- "Error getting the use_gpio_attr");
-
- FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SP_MODE, i_target_chip, l_is_fsp), "Error getting ATTR_IS_SP_MODE");
-
- //For DD2 and beyond we want to use the lpc reset that will reset the external LPC Bus attached devices -- this is what was broken in DD1
- if (l_use_gpio == 0)
- {
- //Write to the LPCM OPB Master Control Register (address x'C001 0008')
- fapi2::buffer<uint64_t> l_lpcm_opb_master_control_register_data(0);
- l_lpcm_opb_master_control_register_data.setBit<PU_LPC_CMD_REG_RNW>().insertFromRight<PU_LPC_CMD_REG_ADR, PU_LPC_CMD_REG_ADR_LEN>
- (LPCM_OPB_MASTER_CONTROL_REG).insertFromRight<PU_LPC_CMD_REG_SIZE, PU_LPC_CMD_REG_SIZE_LEN>(0x4);
- FAPI_TRY(fapi2::putScom(i_target_chip, PU_LPC_CMD_REG, l_lpcm_opb_master_control_register_data),
- "Erro writing the LPC_CMD_REG to get the current reset value");
- FAPI_TRY(fapi2::getScom(i_target_chip, PU_LPC_DATA_REG, l_data64), "Error getting the reset value");
- //Set register bit 23 lpc_lreset_oe to b'1'
- l_data64.setBit<LPC_LRESET_OE>();
- l_lpcm_opb_master_control_register_data.clearBit<PU_LPC_CMD_REG_RNW>();
- FAPI_TRY(fapi2::putScom(i_target_chip, PU_LPC_CMD_REG, l_lpcm_opb_master_control_register_data),
- "Error writing to the LPC_CMD_REG to set lpc_lreset_oe");
- FAPI_TRY(fapi2::putScom(i_target_chip, PU_LPC_DATA_REG, l_data64), "Error setting lpc_lreset_oe");
- //Set register bit 22 lpc_reset_out to b'1'
- l_data64.setBit<LPC_LRESET_OUT>();
- FAPI_TRY(fapi2::putScom(i_target_chip, PU_LPC_CMD_REG, l_lpcm_opb_master_control_register_data),
- "Error writing to the LPC_CMD_REG to set the lpc_reset_out");
- FAPI_TRY(fapi2::putScom(i_target_chip, PU_LPC_DATA_REG, l_data64), "Error setting lpc_reset_out");
- //Clear register bits 22 and 23 to b'00'
- l_data64.clearBit<LPC_LRESET_OE>().clearBit<LPC_LRESET_OUT>();
- FAPI_TRY(fapi2::putScom(i_target_chip, PU_LPC_CMD_REG, l_lpcm_opb_master_control_register_data),
- "Error writing to the LPC_CMD_REG to clear lpc_lreset_oe and lpc_reset_out");
- FAPI_TRY(fapi2::putScom(i_target_chip, PU_LPC_DATA_REG, l_data64), "Error clearing lpc_lreset_oe and lpc_reset_out");
- }
-
- if ((l_use_gpio != 0) && (l_is_fsp == fapi2::ENUM_ATTR_IS_SP_MODE_FSP))
- {
- //LPC Reset active
- l_data64.flush<1>().clearBit<0>();
- FAPI_TRY(fapi2::putScom(i_target_chip, PU_GPIO_OUTPUT_SCOM2, l_data64));
-
- //Set GPI0 output enable
- FAPI_TRY(fapi2::getScom(i_target_chip, PU_GPIO_OUTPUT_EN, l_data64));
- l_data64.setBit<PU_GPIO_OUTPUT_EN_DO_EN_0>();
- FAPI_TRY(fapi2::putScom(i_target_chip, PU_GPIO_OUTPUT_EN, l_data64));
- }
//Do the functional reset that resets the internal registers
- //Settting registers to do an LPC functional reset
+ //Setting registers to do an LPC functional reset
l_data64.flush<0>().setBit<CPLT_CONF1_TC_LP_RESET>();
FAPI_TRY(fapi2::putScom(i_target_chip, PERV_N3_CPLT_CONF1_OR, l_data64));
@@ -122,18 +70,116 @@ fapi2::ReturnCode p9_sbe_lpc_init(const
l_data64.flush<0>().setBit<CPLT_CONF1_TC_LP_RESET>();
FAPI_TRY(fapi2::putScom(i_target_chip, PERV_N3_CPLT_CONF1_CLEAR, l_data64));
- if ((l_use_gpio != 0) && (l_is_fsp == fapi2::ENUM_ATTR_IS_SP_MODE_FSP))
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+static fapi2::ReturnCode reset_lpc_bus_via_master(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target_chip)
+{
+ fapi2::buffer<uint64_t> l_data64;
+ fapi2::buffer<uint64_t> l_lpcm_opb_master_control_register_data(0);
+
+ //Write to the LPCM OPB Master Control Register (address x'C001 0008')
+ l_lpcm_opb_master_control_register_data.setBit<PU_LPC_CMD_REG_RNW>().insertFromRight<PU_LPC_CMD_REG_ADR, PU_LPC_CMD_REG_ADR_LEN>
+ (LPCM_OPB_MASTER_CONTROL_REG).insertFromRight<PU_LPC_CMD_REG_SIZE, PU_LPC_CMD_REG_SIZE_LEN>(0x4);
+ FAPI_TRY(fapi2::putScom(i_target_chip, PU_LPC_CMD_REG, l_lpcm_opb_master_control_register_data),
+ "Erro writing the LPC_CMD_REG to get the current reset value");
+ FAPI_TRY(fapi2::getScom(i_target_chip, PU_LPC_DATA_REG, l_data64), "Error getting the reset value");
+
+ //Set register bit 23 lpc_lreset_oe to b'1' and set lpc_lreset_out to b'0' to drive a low reset
+ l_data64.setBit<LPC_LRESET_OE>().clearBit<LPC_LRESET_OUT>();
+ l_lpcm_opb_master_control_register_data.clearBit<PU_LPC_CMD_REG_RNW>();
+ FAPI_TRY(fapi2::putScom(i_target_chip, PU_LPC_CMD_REG, l_lpcm_opb_master_control_register_data),
+ "Error writing to the LPC_CMD_REG to set lpc_lreset_oe");
+ FAPI_TRY(fapi2::putScom(i_target_chip, PU_LPC_DATA_REG, l_data64), "Error setting lpc_lreset_oe");
+
+ //Give the bus some time to reset
+ fapi2::delay(LPC_LRESET_DELAY_NS, LPC_LRESET_DELAY_NS);
+
+ //Clear bit 23 lpc_lreset_oe to stop driving the low reset
+ l_data64.clearBit<LPC_LRESET_OE>();
+ l_lpcm_opb_master_control_register_data.clearBit<PU_LPC_CMD_REG_RNW>();
+ FAPI_TRY(fapi2::putScom(i_target_chip, PU_LPC_CMD_REG, l_lpcm_opb_master_control_register_data),
+ "Error writing to the LPC_CMD_REG to clear lpc_lreset_oe");
+ FAPI_TRY(fapi2::putScom(i_target_chip, PU_LPC_DATA_REG, l_data64), "Error clearing lpc_lreset_oe");
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+static fapi2::ReturnCode reset_lpc_bus_via_gpio(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target_chip)
+{
+ fapi2::buffer<uint64_t> l_data64;
+
+ //LPC Reset active
+ l_data64.flush<1>().clearBit<0>();
+ FAPI_TRY(fapi2::putScom(i_target_chip, PU_GPIO_OUTPUT_SCOM2, l_data64));
+
+ //Set GPI0 output enable
+ FAPI_TRY(fapi2::getScom(i_target_chip, PU_GPIO_OUTPUT_EN, l_data64));
+ l_data64.setBit<PU_GPIO_OUTPUT_EN_DO_EN_0>();
+ FAPI_TRY(fapi2::putScom(i_target_chip, PU_GPIO_OUTPUT_EN, l_data64));
+
+ //Give the bus some time to reset
+ fapi2::delay(LPC_LRESET_DELAY_NS, LPC_LRESET_DELAY_NS);
+
+ //Unset GPIO output enable
+ FAPI_TRY(fapi2::getScom(i_target_chip, PU_GPIO_OUTPUT_EN, l_data64));
+ l_data64.clearBit<PU_GPIO_OUTPUT_EN_DO_EN_0>();
+ FAPI_TRY(fapi2::putScom(i_target_chip, PU_GPIO_OUTPUT_EN, l_data64));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+fapi2::ReturnCode p9_sbe_lpc_init(
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target_chip)
+{
+ const uint64_t C_LPC_TIMEOUT_ADDR = 0x00400000C001202C;
+ const uint64_t C_LPC_TIMEOUT_DATA = 0x00000000FE000000;
+ const uint64_t C_OPB_TIMEOUT_ADDR = 0x00400000C0010040;
+ const uint64_t C_OPB_TIMEOUT_DATA = 0x00000000FFFFFFFE;
+ fapi2::buffer<uint64_t> l_data64;
+ uint8_t l_use_gpio = 0;
+ uint8_t l_is_fsp = 0;
+ FAPI_DBG("p9_sbe_lpc_init: Entering ...");
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_LPC_RESET_GPIO, i_target_chip, l_use_gpio),
+ "Error getting the use_gpio_attr");
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SP_MODE, i_target_chip, l_is_fsp), "Error getting ATTR_IS_SP_MODE");
+
+ //------------------------------------------------------------------------------------------
+ //--- STEP 1: Functional reset of LPC Master
+ //------------------------------------------------------------------------------------------
+ FAPI_TRY(reset_lpc_master(i_target_chip));
+
+ //------------------------------------------------------------------------------------------
+ //--- STEP 2: Issue an LPC bus reset
+ //------------------------------------------------------------------------------------------
+ //For DD2 and beyond we want to use the lpc reset that will reset the external LPC Bus attached devices -- this is what was broken in DD1
+ if (l_use_gpio == 0)
+ {
+ FAPI_TRY(reset_lpc_bus_via_master(i_target_chip));
+ }
+ else if (l_is_fsp == fapi2::ENUM_ATTR_IS_SP_MODE_FSP)
{
- //LPC Reset Disabled
- l_data64.flush<0>().setBit<0>();
- FAPI_TRY(fapi2::putScom(i_target_chip, PU_GPIO_OUTPUT_SCOM1, l_data64));
-
- //Unset GPIO output enable
- FAPI_TRY(fapi2::getScom(i_target_chip, PU_GPIO_OUTPUT_EN, l_data64));
- l_data64.clearBit<PU_GPIO_OUTPUT_EN_DO_EN_0>();
- FAPI_TRY(fapi2::putScom(i_target_chip, PU_GPIO_OUTPUT_EN, l_data64));
+ FAPI_TRY(reset_lpc_bus_via_gpio(i_target_chip));
}
+ //------------------------------------------------------------------------------------------
+ //--- STEP 3: Program settings in LPC Master and FPGA
+ //------------------------------------------------------------------------------------------
+
//Set up the LPC timeout settings
l_data64 = C_LPC_TIMEOUT_ADDR;
FAPI_TRY(fapi2::putScom(i_target_chip, PU_LPC_CMD_REG, l_data64), "Error tring to set LPC timeout address");
diff --git a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_lpc_init.H b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_lpc_init.H
index 294b37443..c9ff1eef0 100644
--- a/src/import/chips/p9/procedures/hwp/perv/p9_sbe_lpc_init.H
+++ b/src/import/chips/p9/procedures/hwp/perv/p9_sbe_lpc_init.H
@@ -53,6 +53,7 @@ extern "C"
{
const uint64_t LPC_LRESET_OE = 23;
const uint64_t LPC_LRESET_OUT = 22;
+ const uint32_t LPC_LRESET_DELAY_NS = 200000;
const uint64_t LPCM_OPB_MASTER_CONTROL_REG = 0xC0010008;
const uint32_t CPLT_CONF1_TC_LP_RESET = 12;
fapi2::ReturnCode p9_sbe_lpc_init(const
OpenPOWER on IntegriCloud