summaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--src/usr/gpio/gpiodd.C7
-rw-r--r--src/usr/hwpf/hwp/dram_training/palmetto_vddr.C169
-rwxr-xr-xsrc/usr/targeting/common/genHwsvMrwXml.pl119
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types_hb.xml14
4 files changed, 280 insertions, 29 deletions
diff --git a/src/usr/gpio/gpiodd.C b/src/usr/gpio/gpiodd.C
index 4dc94650e..5b2c840e7 100644
--- a/src/usr/gpio/gpiodd.C
+++ b/src/usr/gpio/gpiodd.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. */
/* */
@@ -308,10 +308,7 @@ errlHndl_t gpioReadAttributes ( TARGETING::Target * i_target,
if( !err )
{
- //TODO - RTC 109570 until the the Palmetto attribute file is setup
- io_gpioInfo.i2cMasterPath =
- i_target->getAttr<TARGETING::ATTR_PHYS_PATH>();
- //io_gpioInfo.i2cMasterPath = gpioData.i2cMasterPath;
+ io_gpioInfo.i2cMasterPath = gpioData.i2cMasterPath;
io_gpioInfo.engine = gpioData.engine;
io_gpioInfo.i2cPort = gpioData.port;
io_gpioInfo.i2cDeviceAddr = gpioData.devAddr;
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);
}
diff --git a/src/usr/targeting/common/genHwsvMrwXml.pl b/src/usr/targeting/common/genHwsvMrwXml.pl
index 8bfe40097..b63d4db9a 100755
--- a/src/usr/targeting/common/genHwsvMrwXml.pl
+++ b/src/usr/targeting/common/genHwsvMrwXml.pl
@@ -396,6 +396,19 @@ use constant MAX_NUM_PHB_PER_PROC => 4;
# MAX lane settings value is 32 bytes per phb and is hard coded here
use constant MAX_LANE_SETTINGS_PER_PHB => 32;
+################################################################################
+# If value is hex, convert to regular number
+###############################################################################
+
+sub unhexify {
+ my($val) = @_;
+ if($val =~ m/^0[xX][01234567890A-Fa-f]+$/)
+ {
+ $val = hex($val);
+ }
+ return $val;
+}
+
# Determine values of proc pcie attributes
# Currently
# PROC_PCIE_LANE_EQUALIZATION PROC_PCIE_IOP_CONFIG PROC_PCIE_PHB_ACTIVE
@@ -1234,6 +1247,67 @@ for my $i ( 0 .. $#SMembuses )
}
#------------------------------------------------------------------------------
+# Process VDDR GPIO enables
+#------------------------------------------------------------------------------
+
+my %vddrEnableHash = ();
+my $useGpioToEnableVddr = 0;
+
+if(!$haveFSPs)
+{
+ $useGpioToEnableVddr = 1;
+}
+
+if($useGpioToEnableVddr)
+{
+ my $vddrEnablesFile = open_mrw_file($mrwdir, "${sysname}-vddr.xml");
+ my $vddrEnables = parse_xml_file(
+ $vddrEnablesFile,
+ forcearray=>['vddr-enable']);
+
+ foreach my $vddrEnable (@{$vddrEnables->{'vddr-enable'}})
+ {
+ # Get dependent Centaur info
+ my $centaurNode = $vddrEnable->{'centaur-target'}->{node};
+ my $centaurPosition = $vddrEnable->{'centaur-target'}->{position};
+
+ # Get I2C master which drives the GPIO for this Centaur
+ my $i2cMasterNode = $vddrEnable->{i2c}->{'master-target'}->{node};
+ my $i2cMasterPosition
+ = $vddrEnable->{i2c}->{'master-target'}->{position};
+ my $i2cMasterPort = $vddrEnable->{i2c}->{port};
+ my $i2cMasterEngine = $vddrEnable->{i2c}->{engine};
+
+ # Get GPIO expander info. For now these are pca9535 specific
+ # Targeting requires real i2c address to be shifted left one bit
+ my $i2cAddress = unhexify( $vddrEnable->{i2c}->{address} ) << 1;
+ my $i2cAddressHexStr = sprintf("0x%X",$i2cAddress);
+ my $vddrPort = $vddrEnable->{'io-expander'}->{port};
+ my $vddrPortPin = $vddrEnable->{'io-expander'}->{pin};
+ my $vddrPin = $vddrPort * 8 + $vddrPortPin;
+
+ # Build foreign keys to the Centaur targets
+ my $vddrKey = "n" . $centaurNode . "p" . $centaurPosition;
+ my $i2cMasterKey = "n" . $i2cMasterNode . "p" . $i2cMasterPosition;
+ my $i2cMasterEntityPath =
+ "physical:sys-0/node-$i2cMasterNode/membuf-$i2cMasterPosition";
+
+ # Populate the key => value pairs for a given Centaur
+ $vddrEnableHash{$vddrKey} = {
+ 'i2cMasterKey' => $i2cMasterKey,
+ 'i2cMasterEntityPath' => $i2cMasterEntityPath,
+ 'i2cMasterNode' => $i2cMasterNode,
+ 'i2cMasterPosition' => $i2cMasterPosition,
+ 'i2cMasterPort' => $i2cMasterPort,
+ 'i2cMasterEngine' => $i2cMasterEngine,
+ 'i2cAddress' => $i2cAddress,
+ 'i2cAddressHexStr' => $i2cAddressHexStr,
+ 'vddrPin' => $vddrPin,
+ };
+ }
+}
+
+#------------------------------------------------------------------------------
# Process the i2c-busses MRW file
#------------------------------------------------------------------------------
my $i2c_busses_file = open_mrw_file($mrwdir, "${sysname}-i2c-busses.xml");
@@ -4056,6 +4130,51 @@ sub generate_centaur
addI2cBusSpeedArray($sys, $node, $ctaur, "memb");
}
+ if($useGpioToEnableVddr)
+ {
+ my $vddrKey = "n" . $node . "p" . $ctaur;
+ if(!exists $vddrEnableHash{$vddrKey})
+ {
+ die "FATAL! Cannot find required GPIO info for memory buffer "
+ . "$vddrKey VDDR enable.\n"
+ }
+ elsif(!exists $vddrEnableHash{$vddrEnableHash{$vddrKey}{i2cMasterKey}})
+ {
+ die "FATAL! Must reference real membuf as I2C master for VDDR "
+ . "enable. Membuf $vddrEnableHash{$vddrKey}{i2cMasterKey} "
+ . "requested.\n";
+ }
+ else
+ {
+ print
+"\n <attribute>
+ <id>GPIO_INFO</id>
+ <default>
+ <field>
+ <id>i2cMasterPath</id>
+ <value>$vddrEnableHash{$vddrKey}{i2cMasterEntityPath}</value>
+ </field>
+ <field>
+ <id>port</id>
+ <value>$vddrEnableHash{$vddrKey}{i2cMasterPort}</value>
+ </field>
+ <field>
+ <id>devAddr</id>
+ <value>$vddrEnableHash{$vddrKey}{i2cAddressHexStr}</value>
+ </field>
+ <field>
+ <id>engine</id>
+ <value>$vddrEnableHash{$vddrKey}{i2cMasterEngine}</value>
+ </field>
+ <field>
+ <id>vddrPin</id>
+ <value>$vddrEnableHash{$vddrKey}{vddrPin}</value>
+ </field>
+ </default>
+ </attribute>\n";
+ }
+ }
+
print "\n</targetInstance>\n";
}
diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
index bc16e0854..57fb8e654 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
@@ -279,21 +279,21 @@
<description>Entity path to the chip that contains the I2C
master</description>
<type>EntityPath</type>
- <default>physical:sys-0/node-0/membuf-0</default>
+ <default>physical:sys-0</default>
</field>
<field>
<name>port</name>
<description>Port from the I2C Master device. This is a 6-bit
value.</description>
<type>uint8_t</type>
- <default>1</default>
+ <default>0</default>
</field>
<field>
<name>devAddr</name>
<description>Device address on the I2C bus. This is a 7-bit value,
but then shifted 1 bit left.</description>
<type>uint8_t</type>
- <default>0x40</default>
+ <default>0</default>
</field>
<field>
<name>engine</name>
@@ -302,6 +302,14 @@
<type>uint8_t</type>
<default>0</default>
</field>
+ <field>
+ <name>vddrPin</name>
+ <description>
+ Logical GPIO pin number used to enabled/disable VDDR
+ </description>
+ <type>uint8_t</type>
+ <default>0</default>
+ </field>
</complexType>
<persistency>non-volatile</persistency>
<readable/>
OpenPOWER on IntegriCloud