summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf/hwp/dram_training
diff options
context:
space:
mode:
authorNick Bofferding <bofferdn@us.ibm.com>2014-12-04 14:16:09 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2015-01-22 17:17:39 -0600
commitf8569146fb30162c9bc9d4730d0476f209071fac (patch)
tree19a495e078dea43580c38cb4c999cb4eac1e909e /src/usr/hwpf/hwp/dram_training
parent1bc13e89d35eacba76589ac3c5158d54ce73b35b (diff)
downloadtalos-hostboot-f8569146fb30162c9bc9d4730d0476f209071fac.tar.gz
talos-hostboot-f8569146fb30162c9bc9d4730d0476f209071fac.zip
Support VDDR enable for Firestone
- Assert GPIOs from MRW info to enable VDDR across FSP-less platforms - Updated MRW parser to parse GPIO info from MRW - Updated membuf selection algorithm to choose optimal set of GPIO enables - Defaulted GPIO_INFO attribute to invalid value - Updated GPIO device driver to use MRW i2c master path Change-Id: I0da9e0608af3e8368217c863b2606279637711e5 RTC: 117706 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/14710 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/hwpf/hwp/dram_training')
-rw-r--r--src/usr/hwpf/hwp/dram_training/palmetto_vddr.C169
1 files changed, 148 insertions, 21 deletions
diff --git a/src/usr/hwpf/hwp/dram_training/palmetto_vddr.C b/src/usr/hwpf/hwp/dram_training/palmetto_vddr.C
index 5286d26f6..b456324a4 100644
--- a/src/usr/hwpf/hwp/dram_training/palmetto_vddr.C
+++ b/src/usr/hwpf/hwp/dram_training/palmetto_vddr.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014 */
+/* Contributors Listed Below - COPYRIGHT 2014,2015 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -29,6 +29,8 @@
#include "platform_vddr.H"
+#include <string.h>
+
#include <hwpf/hwpf_reasoncodes.H>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
@@ -48,17 +50,6 @@ using namespace DeviceFW;
trace_desc_t* g_trac_vddr = NULL;
TRAC_INIT(&g_trac_vddr, "HB_VDDR", KILOBYTE);
-/**
- * PCA95X GPIO function assignements
- */
-enum
-{
- // Output GPIO to enable VDDR. (GPIO pin 0)
- GPIO_P1V35_EN = 0,
-
- // No other GPIO pins are implemented on the Palmetto board
-};
-
// PCA95X internal register addresses
enum
{
@@ -80,14 +71,101 @@ enum
// Helper function to call provided function pointer on each functional
// centaur Target.
-static errlHndl_t for_each_centaur(errlHndl_t (*func)(Target *))
+
+//******************************************************************************
+// compareTargetsGpioInfos
+//******************************************************************************
+
+bool compareTargetsGpioInfos(
+ TARGETING::TargetHandle_t i_pLhs,
+ TARGETING::TargetHandle_t i_pRhs)
+{
+
+ TARGETING::ATTR_GPIO_INFO_type lhsGpioInfo =
+ i_pLhs->getAttr<TARGETING::ATTR_GPIO_INFO>();
+ TARGETING::ATTR_GPIO_INFO_type rhsGpioInfo =
+ i_pRhs->getAttr<TARGETING::ATTR_GPIO_INFO>();
+
+ // Code logically compares left hand side (lhs) target to right hand side
+ // (rhs) target with respect to GPIO info and returns true if the left hand
+ // side is logically before the right hand side. To make the computation,
+ // compare first GPIO info field for each object. If values are not
+ // logically equal, return whether the left hand side value was less than
+ // the right hand side value. Otherwise break the tie by comparing the
+ // next GPIO field in similar fashion. Continue breaking ties until the
+ // last field, in which case a tie returns false.
+ bool lhsLogicallyBeforeRhs =
+ lhsGpioInfo.i2cMasterPath < rhsGpioInfo.i2cMasterPath;
+ if(lhsGpioInfo.i2cMasterPath == rhsGpioInfo.i2cMasterPath)
+ {
+ lhsLogicallyBeforeRhs = lhsGpioInfo.port < rhsGpioInfo.port;
+ if(lhsGpioInfo.port == rhsGpioInfo.port)
+ {
+ lhsLogicallyBeforeRhs = lhsGpioInfo.engine < rhsGpioInfo.engine;
+ if(lhsGpioInfo.engine == rhsGpioInfo.engine)
+ {
+ lhsLogicallyBeforeRhs
+ = lhsGpioInfo.devAddr < rhsGpioInfo.devAddr;
+ if(lhsGpioInfo.devAddr == rhsGpioInfo.devAddr)
+ {
+ lhsLogicallyBeforeRhs =
+ lhsGpioInfo.vddrPin < rhsGpioInfo.vddrPin;
+ }
+ }
+ }
+ }
+
+ return lhsLogicallyBeforeRhs;
+}
+
+//******************************************************************************
+// areTargetsGpioInfoEqual
+//******************************************************************************
+
+bool areTargetsGpioInfoEqual(
+ TARGETING::TargetHandle_t i_pLhs,
+ TARGETING::TargetHandle_t i_pRhs)
+{
+
+ TARGETING::ATTR_GPIO_INFO_type lhsGpioInfo =
+ i_pLhs->getAttr<TARGETING::ATTR_GPIO_INFO>();
+ TARGETING::ATTR_GPIO_INFO_type rhsGpioInfo =
+ i_pRhs->getAttr<TARGETING::ATTR_GPIO_INFO>();
+
+ return( ( lhsGpioInfo.i2cMasterPath
+ == rhsGpioInfo.i2cMasterPath)
+ && ( lhsGpioInfo.port
+ == rhsGpioInfo.port)
+ && ( lhsGpioInfo.engine
+ == rhsGpioInfo.engine)
+ && ( lhsGpioInfo.devAddr
+ == rhsGpioInfo.devAddr)
+ && ( lhsGpioInfo.vddrPin
+ == rhsGpioInfo.vddrPin) );
+}
+
+static errlHndl_t for_each_vddr_domain_with_functional_memory(
+ errlHndl_t (*func)(Target *))
{
- // Get all Centaur targets
+ // Get all functional Centaur targets
TargetHandleList l_membufTargetList;
getAllChips(l_membufTargetList, TYPE_MEMBUF);
errlHndl_t l_err = NULL;
+ // Sort chips in order of GPIO info
+ std::sort(l_membufTargetList.begin(), l_membufTargetList.end(),
+ compareTargetsGpioInfos);
+
+ // Prune out targets with non-unique GPIO info
+ std::vector<TARGETING::TargetHandle_t>::iterator
+ pInvalidEntries = std::unique(
+ l_membufTargetList.begin(),
+ l_membufTargetList.end(),
+ areTargetsGpioInfoEqual);
+ l_membufTargetList.erase(pInvalidEntries,l_membufTargetList.end());
+
+ // Invoke callback for one Centaur per unique VDDR domain
for (TargetHandleList::iterator
l_membuf_iter = l_membufTargetList.begin();
l_membuf_iter != l_membufTargetList.end();
@@ -196,19 +274,66 @@ static errlHndl_t pca95xGpioWriteBit(TARGETING::Target * i_target,
return err;
}
-static errlHndl_t palmetto_centaur_enable_vddr(Target *centaur)
+static errlHndl_t enableVddrViaGpioPinStrategy(Target *centaur)
{
errlHndl_t l_err = NULL;
- // Enable the DIMM power.
- l_err = pca95xGpioWriteBit(centaur, GPIO_P1V35_EN, true);
+ do
+ {
+ // Enable the DIMM power.
+ TARGETING::ATTR_GPIO_INFO_type gpioInfo =
+ centaur->getAttr<TARGETING::ATTR_GPIO_INFO>();
+
+ l_err = pca95xGpioWriteBit(centaur, gpioInfo.vddrPin, true);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_vddr,ERR_MRK " "
+ "Failed to assert pca95x GPIO for Centaur HUID = 0x%08x "
+ "and pin %d.",
+ TARGETING::get_huid(centaur),gpioInfo.vddrPin);
+ break;
+ }
+
+ TRACFCOMP(g_trac_vddr,INFO_MRK " "
+ "Enabled VDDR for Centaur HUID = 0x%08x (asserted pca95x GPIO "
+ "pin %d).",
+ TARGETING::get_huid(centaur),
+ gpioInfo.vddrPin);
+
+ } while(0);
return l_err;
}
-static errlHndl_t palmetto_centaur_disable_vddr(Target *centaur)
+static errlHndl_t disableVddrViaGpioPinStrategy(Target *centaur)
{
- return pca95xGpioWriteBit(centaur, GPIO_P1V35_EN, false);
+ errlHndl_t l_err = NULL;
+
+ do
+ {
+ // Disable the DIMM power.
+ TARGETING::ATTR_GPIO_INFO_type gpioInfo =
+ centaur->getAttr<TARGETING::ATTR_GPIO_INFO>();
+
+ l_err = pca95xGpioWriteBit(centaur,gpioInfo.vddrPin, false);
+ if(l_err)
+ {
+ TRACFCOMP(g_trac_vddr,ERR_MRK " "
+ "Failed to deassert pca95x GPIO for Centaur HUID = 0x%08x "
+ "and pin %d.",
+ TARGETING::get_huid(centaur),gpioInfo.vddrPin);
+ break;
+ }
+
+ TRACFCOMP(g_trac_vddr,INFO_MRK " "
+ "Disabled VDDR for Centaur HUID = 0x%08x (deasserted pca95x GPIO "
+ "pin %d).",
+ TARGETING::get_huid(centaur),
+ gpioInfo.vddrPin);
+
+ } while(0);
+
+ return l_err;
}
// External interfaces
@@ -222,10 +347,12 @@ errlHndl_t platform_enable_vspd()
errlHndl_t platform_enable_vddr()
{
- return for_each_centaur(palmetto_centaur_enable_vddr);
+ return for_each_vddr_domain_with_functional_memory(
+ enableVddrViaGpioPinStrategy);
}
errlHndl_t platform_disable_vddr()
{
- return for_each_centaur(palmetto_centaur_disable_vddr);
+ return for_each_vddr_domain_with_functional_memory(
+ disableVddrViaGpioPinStrategy);
}
OpenPOWER on IntegriCloud