the following patch was just integrated into master:
commit f35ce497d1bbf646e3397ba34dc350b43ac81a44
Author: Paul Menzel <paulepanter(a)users.sourceforge.net>
Date: Wed Feb 27 11:17:59 2013 +0100
ASRock E350M1: Remove non-existing PCI devices 12.1 and 13.1
Looking at the coreboot log
[…]
PCI: 00:12.0 [1002/4397] enabled
sb800_enable() PCI: Static device PCI: 00:12.1 not found, disabling it.
sb800_enable() PCI: 00:12.2 [1002/4396] ops
PCI: 00:12.2 [1002/4396] enabled
sb800_enable() PCI: 00:13.0 [1002/4397] ops
PCI: 00:13.0 [1002/4397] enabled
sb800_enable() PCI: Static device PCI: 00:13.1 not found, disabling it.
sb800_enable() PCI: 00:13.2 [1002/4396] ops
PCI: 00:13.2 [1002/4396] enabled
[…]
and the `lspci -tnvv` output running the proprietary vendor BIOS
attached to the Wiki page of the ASRock E350M1 [1][2]
-[0000:00]-+-00.0 1022:1510
+-01.0 1002:9802
+-01.1 1002:1314
+-04.0-[01]--
+-11.0 1002:4391
+-12.0 1002:4397
+-12.2 1002:4396
+-13.0 1002:4397
+-13.2 1002:4396
[…]
both PCI devices do not exist, so remove them from `devicetree.cb`.
Commit 48918f7 [3]
Persimmon, Inagua: PCI devs 12.1, 13.1 (USB) don't exist, but 14.6 (GEC) does
did the same for AMD Inagua and AMD Persimmon.
[1] http://www.coreboot.org/ASRock_E350M1
[2] http://www.coreboot.org/File:ASRock_E350M1_info_dump.tar.bz2
[3] http://review.coreboot.org/2463
Change-Id: Ief6de1bda093d1f29d5925985e5c3839cdded537
Signed-off-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
Reviewed-on: http://review.coreboot.org/2536
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martin.roth(a)se-eng.com>
Build-Tested: build bot (Jenkins) at Wed Feb 27 11:59:36 2013, giving +1
Reviewed-By: Martin Roth <martin.roth(a)se-eng.com> at Sat Mar 2 02:13:44 2013, giving +2
See http://review.coreboot.org/2536 for details.
-gerrit
the following patch was just integrated into master:
commit f91c8f290b2a723d1bda9a5dd7d668390672317e
Author: Jens Rottmann <JRottmann(a)LiPPERTembedded.de>
Date: Fri Mar 1 19:01:00 2013 +0100
FrontRunner/Toucan-AF: work around AGESA RAM init crashing on reboot
If you try to reset the system with outb(3,0x92), outb(4,0xcf9) or a
triple-fault it will instead crash with a messy screen. As the more common
outb(0xFE, 0x64) doesn't work with our setup, Linux will crash whenever you
ask it to reboot. Closer inspection shows that on a warm boot of Coreboot
agesawrapper_amdinitpost() always fails with error code 7. Looks like DDR3
re-init goes wrong somehow. I tried find the reason for this but was
unable to. I am convinced this is not board specific but a bug in AGESA.
In the end I had to settle for a workaround: if amdinitpost returns 7 this
patch resets the system harder with outb(0x06, 0x0cf9), after that RAM init
will succeed. As amdinitpost is early in POST this automatic reset is
quick enough not to be noticable.
I'd perfer a real fix, but that's all I have.
Change-Id: I4763254b489f42a135232e45328ecf0d5c4d961a
Signed-off-by: Jens Rottmann <JRottmann(a)LiPPERTembedded.de>
Reviewed-on: http://review.coreboot.org/2573
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
Build-Tested: build bot (Jenkins) at Fri Mar 1 21:58:08 2013, giving +1
Reviewed-By: Stefan Reinauer <stefan.reinauer(a)coreboot.org> at Sat Mar 2 00:18:08 2013, giving +2
See http://review.coreboot.org/2573 for details.
-gerrit
the following patch was just integrated into master:
commit 68c9f2bdc50d5bf51a3d09dc6ebc51bed2ec5d30
Author: Jens Rottmann <JRottmann(a)LiPPERTembedded.de>
Date: Fri Mar 1 17:20:42 2013 +0100
LiPPERT Toucan-AF [2/2]: actually implement mainboard support
Step 2: change the Persimmon code to adapt it to the new board's hardware.
The Toucan-AF is a COM Express Compact Type 6 form factor embedded board:
- AMD Fusion G-T56N (1.65 GHz dual core) or T40R (1 GHz single core) APU
- 1-4 GB DDR3 memory down
- 1x VGA, 2x DisplayPort (1 switchable to LVDS)
- AMD A55E (Hudson-E1) southbridge
- 8x USB 2.0
- 4x SATA
- HD Audio (with codec on baseboard)
- NEC uPD78F0532 microcontroller on I2C ("SEMA")
- 7x PCIe2.0 x1 (1 on PEG)
- Intel I210 GbE (on APU PCIe x1, can be disabled for additional PCIe)
- 2x SST 25VF032B (SO8, soldered) 4 MB SPI flash (BIOS and failsafe BIOS)
The Toucan-AF has no SIO on board. This patch includes basic support for a
Winbond W83627DHG (PS/2, 2x RS232), because the ADLINK ExpressBase-6 used
for evaluation happens to have one. The code may have to be adapted to the
actual baseboard of the application.
http://www.adlinktech.com/PD/web/PD_detail.php?pid=1132
Change-Id: I9041b905bad45852ac9b402fcbd5decbc98b377b
Signed-off-by: Jens Rottmann <JRottmann(a)LiPPERTembedded.de>
Reviewed-on: http://review.coreboot.org/2572
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
Build-Tested: build bot (Jenkins) at Fri Mar 1 21:48:26 2013, giving +1
Reviewed-By: Stefan Reinauer <stefan.reinauer(a)coreboot.org> at Sat Mar 2 00:16:38 2013, giving +2
See http://review.coreboot.org/2572 for details.
-gerrit
the following patch was just integrated into master:
commit 1664404652e2db51845e21db302d162a63eb0347
Author: Jens Rottmann <JRottmann(a)LiPPERTembedded.de>
Date: Fri Mar 1 17:12:56 2013 +0100
LiPPERT Toucan-AF [1/2]: create board by forking AMD Persimmon
Step 1: copy all files unmodified from Persimmon. This makes it much
easier later to see how the two boards actually and deliberately differ
when porting bugfixes from one to the other. Git's copy detection is
imperfect (and slow).
Change-Id: I1ff02913479c07679f8c3ae5e6dd7876e6000b55
Signed-off-by: Jens Rottmann <JRottmann(a)LiPPERTembedded.de>
Reviewed-on: http://review.coreboot.org/2571
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
Build-Tested: build bot (Jenkins) at Fri Mar 1 21:37:38 2013, giving +1
Reviewed-By: Stefan Reinauer <stefan.reinauer(a)coreboot.org> at Sat Mar 2 00:16:26 2013, giving +2
See http://review.coreboot.org/2571 for details.
-gerrit
the following patch was just integrated into master:
commit 73d4965be99cc93cec277afca4cdae979433b2b0
Author: Jens Rottmann <JRottmann(a)LiPPERTembedded.de>
Date: Thu Feb 28 09:56:20 2013 +0100
LiPPERT FrontRunner-AF [1/2]: create board by forking AMD Persimmon
Step 1: copy all files unmodified from Persimmon. This makes it much
easier later to see how the two boards actually and deliberately differ
when porting bugfixes from one to the other. Git's copy detection is
imperfect (and slow).
Change-Id: I2fd1bf8428fc8a1e7becee888b6182b9bd8166a0
Signed-off-by: Jens Rottmann <JRottmann(a)LiPPERTembedded.de>
Reviewed-on: http://review.coreboot.org/2552
Tested-by: build bot (Jenkins)
Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
Reviewed-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
Build-Tested: build bot (Jenkins) at Fri Mar 1 14:48:49 2013, giving +1
Reviewed-By: Stefan Reinauer <stefan.reinauer(a)coreboot.org> at Sat Mar 2 00:12:32 2013, giving +2
See http://review.coreboot.org/2552 for details.
-gerrit
Martin Roth (martin.roth(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2497
-gerrit
commit ebf9d9de1ea732131965da1ecf927ef0b90c03fc
Author: Martin Roth <martin.roth(a)se-eng.com>
Date: Sun Feb 24 10:46:11 2013 -0700
AMD Fam14: Add SPD read functions to wrapper code
Change:
This is the initial step for moving the AMD F14 & HUDSON1,2,3
SPD-read callout out of the mainboard directories and into
the vendorcode. The next step is to update the platforms to use
this routine in BiosCallouts.c and to delete the code from the
mainboard directories. The DIMM addresses should be moved into
devicetree.cb.
If there are significant differences or reasons that the mainboard
needs to override this code, it's perfectly reasonable to keep using
the version in the mainboard, but this allows us to remove duplicated
code and simplify the mainboard directories.
Notes:
This started by duplicating what was in Persimmon, and was changed to
use the devicetree.cb structures. The ASF setup was also removed from
the persimmon copy (PMIO writes to 0x28 & 0x29) as that's not needed
for the SPD access and doesn't make sense to initialize here.
Significant cleanup and magic number reduction was done as well.
It is intended that this file will not be included in ramstage as
the DIMM init is all done in romstage.
This is similar to what was done for Parmer/Thatcher in commit
7fb692bd - http://review.coreboot.org/#/c/2190/
Fam15tn: Move SPD read from mainboards into wrapper
Yes, it would make sense to split this into two separate files
and move the SMBUS initialization and access into the southbridge
wrapper. Maybe that can come next.
Change-Id: I1e106d3912c160b0015bf02158d9faba4f578ee3
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
src/northbridge/amd/agesa/family14/Makefile.inc | 2 +
src/northbridge/amd/agesa/family14/chip.h | 42 +++++++
src/northbridge/amd/agesa/family14/dimmSpd.c | 150 ++++++++++++++++++++++++
src/northbridge/amd/agesa/family14/dimmSpd.h | 83 +++++++++++++
4 files changed, 277 insertions(+)
diff --git a/src/northbridge/amd/agesa/family14/Makefile.inc b/src/northbridge/amd/agesa/family14/Makefile.inc
index 87f4927..e7093fe 100644
--- a/src/northbridge/amd/agesa/family14/Makefile.inc
+++ b/src/northbridge/amd/agesa/family14/Makefile.inc
@@ -17,4 +17,6 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
+romstage-y += dimmSpd.c
+
ramstage-y += northbridge.c
diff --git a/src/northbridge/amd/agesa/family14/chip.h b/src/northbridge/amd/agesa/family14/chip.h
new file mode 100644
index 0000000..56d9c92
--- /dev/null
+++ b/src/northbridge/amd/agesa/family14/chip.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ *
+ * 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
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _NB_AGESA_CHIP_H_
+#define _NB_AGESA_CHIP_H_
+
+struct northbridge_amd_agesa_family14_config
+{
+ /*
+ * Here is an example of how this would be put into the devicetree.cb file
+ * Note that only Socket 0, Channel 0 is used for the Ontario
+ * (family 14, Fam 0x00-0x0F) parts.
+ * This should be placed after the device pci 18.x statements
+ *
+ * register "spdAddrLookup" = "
+ * { // Use 8-bit SPD addresses here
+ * { {0xA0, 0xA2}, {0x00, 0x00}, }, // socket 0 - Channel 0 & 1
+ * { {0x00, 0x00}, {0x00, 0x00}, }, // socket 1 - Channel 0 & 1 (Unused)
+ * }"
+ *
+ */
+
+ u8 spdAddrLookup[2][2][4];
+};
+
+#endif
diff --git a/src/northbridge/amd/agesa/family14/dimmSpd.c b/src/northbridge/amd/agesa/family14/dimmSpd.c
new file mode 100644
index 0000000..9f16e5f
--- /dev/null
+++ b/src/northbridge/amd/agesa/family14/dimmSpd.c
@@ -0,0 +1,150 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/pci_def.h>
+#include <device/device.h>
+#include <stdlib.h>
+#include "OEM.h" /* SMBUS0_BASE_ADDRESS */
+
+/* warning: Porting.h includes an open #pragma pack(1) */
+#include "Porting.h"
+#include "AGESA.h"
+#include "amdlib.h"
+#include "dimmSpd.h"
+#include "chip.h"
+
+/* uncomment for source level debug - GDB gets really confused otherwise. */
+//#pragma optimize ("", off)
+
+/**
+ * Read a single SPD byte. If byte 0 is being read, set up the address
+ * and offset. Following bytes auto increment.
+ */
+static UINT8 readSmbusByte(UINT16 iobase, UINT8 address, char *buffer,
+ int offset)
+{
+ unsigned int status;
+ UINT64 time_limit;
+
+ if (offset == 0) {
+ address |= READ_BIT; /* set read bit */
+
+ /* Clear status, set offset, set slave address and start reading */
+ __outbyte(iobase + SMBUS_STATUS_REG, 0x1E);
+ __outbyte(iobase + SMBUS_SLAVE_STATUS_REG, 0x3E);
+ __outbyte(iobase + SMBUS_CONTROL_REG, offset);
+ __outbyte(iobase + SMBUS_HOST_CMD_REG, address);
+ __outbyte(iobase + SMBUS_COMMAND_REG, SMBUS_READ_BYTE_COMMAND);
+ } else {
+ /* Clear status, issue read command - auto increments to next byte */
+ __outbyte(iobase + SMBUS_STATUS_REG, 0x1E);
+ __outbyte(iobase + SMBUS_COMMAND_REG, SMBUS_READ_COMMAND);
+ }
+
+ /* time limit to avoid hanging for unexpected error status */
+ time_limit = __rdtsc() + MAX_READ_TSC_COUNT;
+ for (;;) {
+ status = __inbyte(iobase + SMBUS_STATUS_REG);
+ if (__rdtsc() > time_limit)
+ break;
+ if ((status & SMBUS_INTERRUPT_MASK) == 0)
+ continue; /* SMBusInterrupt not set, keep waiting */
+ if ((status & HOSTBUSY_MASK) != 0)
+ continue; /* HostBusy set, keep waiting */
+ break;
+ }
+
+ buffer[0] = __inbyte(iobase + SMBUS_DATA0_REG);
+ if (status == STATUS__COMPLETED_SUCCESSFULLY)
+ status = AGESA_SUCCESS;
+ else
+ status = AGESA_ERROR;
+
+ return status;
+}
+
+static void writePmReg(UINT8 reg, UINT8 data)
+{
+ __outbyte(PMIO_INDEX_REG, reg);
+ __outbyte(PMIO_DATA_REG, data);
+}
+
+static void setupFch(UINT16 ioBase)
+{
+ /* set up SMBUS - Set to SMBUS 0 & set base address */
+ /* For SB800 & Hudson1 to SB900 & Hudson 2/3 */
+ writePmReg(SMBUS_BAR_HIGH_BYTE, ioBase >> 8);
+ writePmReg(SMBUS_BAR_LOW_BYTE, (ioBase & 0xe0) | 1);
+
+ /* set SMBus clock to 400 KHz */
+ __outbyte(ioBase + SMBUS_CLOCK_REG, SMBUS_FREQUENCY_CONST / 400000);
+}
+
+/**
+ * Read one or more SPD bytes from a DIMM.
+ * Start with offset zero and read sequentially.
+ * Reads 128 bytes in 7-8 ms at 400 KHz.
+ */
+static UINT8 readspd(UINT16 iobase, UINT8 SmbusSlaveAddress, char *buffer,
+ UINT16 count)
+{
+ UINT16 index;
+ UINT8 status;
+
+ setupFch(iobase);
+
+ for (index = 0; index < count; index++) {
+ status = readSmbusByte(iobase, SmbusSlaveAddress, &buffer[index], index);
+ if (status != AGESA_SUCCESS)
+ return status;
+ }
+
+ return status;
+}
+
+/**
+ * Gets the SMBUS address for an SPD from the array in devicetree.cb
+ * then read the SPD into the supplied buffer.
+ */
+AGESA_STATUS agesa_ReadSPD(UINT32 unused1, UINT32 unused2, void *infoptr)
+{
+ UINT8 spdAddress;
+ UINT16 iobase = SMBUS0_BASE_ADDRESS;
+ AGESA_READ_SPD_PARAMS *info = infoptr;
+ ROMSTAGE_CONST struct device *dev = dev_find_slot(0, PCI_DEVFN(0x18, 2));
+ ROMSTAGE_CONST struct northbridge_amd_agesa_family14_config *config =
+ dev->chip_info;
+
+ if ((dev == 0) || (config == 0))
+ return AGESA_ERROR;
+
+ if (info->SocketId >= ARRAY_SIZE(config->spdAddrLookup))
+ return AGESA_ERROR;
+ if (info->MemChannelId >= ARRAY_SIZE(config->spdAddrLookup[0]))
+ return AGESA_ERROR;
+ if (info->DimmId >= ARRAY_SIZE(config->spdAddrLookup[0][0]))
+ return AGESA_ERROR;
+
+ spdAddress = config->spdAddrLookup
+ [info->SocketId][info->MemChannelId][info->DimmId];
+
+ if (spdAddress == 0)
+ return AGESA_ERROR;
+ return readspd(iobase, spdAddress, (void *)info->Buffer, 128);
+}
diff --git a/src/northbridge/amd/agesa/family14/dimmSpd.h b/src/northbridge/amd/agesa/family14/dimmSpd.h
new file mode 100644
index 0000000..57512c7
--- /dev/null
+++ b/src/northbridge/amd/agesa/family14/dimmSpd.h
@@ -0,0 +1,83 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA02110-1301 USA
+ */
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#ifndef _DIMMSPD_H_
+#define _DIMMSPD_H_
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+#define READ_BIT 0x01
+
+#define SMBUS_INTERRUPT_MASK 0x02
+#define HOSTBUSY_MASK 0x01
+
+#define SMBUS_READ_BYTE_COMMAND 0x48
+#define SMBUS_READ_COMMAND 0x44
+
+#define MAX_READ_TSC_COUNT (2000000000 / 10)
+
+#define PMIO_INDEX_REG 0xCD6
+#define PMIO_DATA_REG 0xCD7
+
+#define SMBUS_BAR_LOW_BYTE 0x2C
+#define SMBUS_BAR_HIGH_BYTE 0x2D
+
+#define SMBUS_STATUS_REG 0x00
+#define SMBUS_SLAVE_STATUS_REG 0x01
+#define SMBUS_COMMAND_REG 0x02
+#define SMBUS_CONTROL_REG 0x03
+#define SMBUS_HOST_CMD_REG 0x04
+#define SMBUS_DATA0_REG 0x05
+#define SMBUS_CLOCK_REG 0x0E
+
+#define STATUS__COMPLETED_SUCCESSFULLY 0x02
+
+#define SMBUS_FREQUENCY_CONST 66000000 / 4
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+AGESA_STATUS
+agesa_ReadSPD (IN UINT32 Func, IN UINT32 Data, IN OUT void *SpdData);
+
+/*---------------------------------------------------------------------------------------
+ * L O C A L F U N C T I O N S
+ *---------------------------------------------------------------------------------------
+ */
+
+#endif
Martin Roth (martin.roth(a)se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2497
-gerrit
commit f4c873a4173dcbf43043912085cd5014ce25a06f
Author: Martin Roth <martin.roth(a)se-eng.com>
Date: Sun Feb 24 10:46:11 2013 -0700
AMD Fam14: Add SPD read functions to wrapper code
Change:
This is the initial step for moving the AMD F14 & HUDSON1,2,3
SPD-read callout out of the mainboard directories and into
the vendorcode. The next step is to update the platforms to use
this routine in BiosCallouts.c and to delete the code from the
mainboard directories. The DIMM addresses should be moved into
devicetree.cb.
If there are significant differences or reasons that the mainboard
needs to override this code, it's perfectly reasonable to keep using
the version in the mainboard, but this allows us to remove duplicated
code and simplify the mainboard directories.
Notes:
This started by duplicating what was in Persimmon, and was changed to
use the devicetree.cb structures. The ASF setup was also removed from
the persimmon copy (PMIO writes to 0x28 & 0x29) as that's not needed
for the SPD access and doesn't make sense to initialize here.
Significant cleanup and magic number reduction was done as well.
It is intended that this file will not be included in ramstage as
the DIMM init is all done in romstage.
This is similar to what was done for Parmer/Thatcher in commit
7fb692bd - http://review.coreboot.org/#/c/2190/
Fam15tn: Move SPD read from mainboards into wrapper
Yes, it would make sense to split this into two separate files
and move the SMBUS initialization and access into the southbridge
wrapper. Maybe that can come next.
Change-Id: I1e106d3912c160b0015bf02158d9faba4f578ee3
Signed-off-by: Martin Roth <martin.roth(a)se-eng.com>
---
src/northbridge/amd/agesa/family14/Makefile.inc | 2 +
src/northbridge/amd/agesa/family14/chip.h | 42 +++++++
src/northbridge/amd/agesa/family14/dimmSpd.c | 150 ++++++++++++++++++++++++
src/northbridge/amd/agesa/family14/dimmSpd.h | 83 +++++++++++++
4 files changed, 277 insertions(+)
diff --git a/src/northbridge/amd/agesa/family14/Makefile.inc b/src/northbridge/amd/agesa/family14/Makefile.inc
index 87f4927..e7093fe 100644
--- a/src/northbridge/amd/agesa/family14/Makefile.inc
+++ b/src/northbridge/amd/agesa/family14/Makefile.inc
@@ -17,4 +17,6 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
+romstage-y += dimmSpd.c
+
ramstage-y += northbridge.c
diff --git a/src/northbridge/amd/agesa/family14/chip.h b/src/northbridge/amd/agesa/family14/chip.h
new file mode 100644
index 0000000..f6e79cc
--- /dev/null
+++ b/src/northbridge/amd/agesa/family14/chip.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC
+ *
+ * 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
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _NB_AGESA_CHIP_H_
+#define _NB_AGESA_CHIP_H_
+
+struct northbridge_amd_agesa_family14_config
+{
+ /*
+ * Here is an example of how this would be put into the devicetree.cb file
+ * Note that only Socket 0, Channel 0 is used for the Ontario
+ * (family 14, Fam 0x00-0x0F) parts.
+ * This should be placed after the device pci 18.x statements
+ *
+ * register "spdAddrLookup" = "
+ * { // Use 8-bit SPD addresses here
+ * { {0xA0, 0xA2}, {0x00, 0x00}, }, // socket 0 - Channel 0 & 1
+ * { {0x00, 0x00}, {0x00, 0x00}, }, // socket 1 - Channel 0 & 1 (Unused)
+ * }"
+ *
+ */
+
+ u8 spdAddrLookup[2][2][4];
+};
+
+#endif
diff --git a/src/northbridge/amd/agesa/family14/dimmSpd.c b/src/northbridge/amd/agesa/family14/dimmSpd.c
new file mode 100644
index 0000000..0793a19
--- /dev/null
+++ b/src/northbridge/amd/agesa/family14/dimmSpd.c
@@ -0,0 +1,150 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/pci_def.h>
+#include <device/device.h>
+#include <stdlib.h>
+#include "OEM.h" /* SMBUS0_BASE_ADDRESS */
+
+/* warning: Porting.h includes an open #pragma pack(1) */
+#include "Porting.h"
+#include "AGESA.h"
+#include "amdlib.h"
+#include "dimmSpd.h"
+#include "chip.h"
+
+/* uncomment for source level debug - GDB gets really confused otherwise. */
+//#pragma optimize ("", off)
+
+/**
+ * Read a single SPD byte. If byte 0 is being read, set up the address
+ * and offset. Following bytes auto increment.
+ */
+static UINT8 readSmbusByte(UINT16 iobase, UINT8 address, char *buffer,
+ int offset)
+{
+ unsigned int status;
+ UINT64 time_limit;
+
+ if (offset == 0) {
+ address |= READ_BIT; /* set read bit */
+
+ /* Clear status, set offset, set slave address and start reading */
+ __outbyte(iobase + SMBUS_STATUS_REG, 0x1E);
+ __outbyte(iobase + SMBUS_SLAVE_STATUS_REG, 0x3E);
+ __outbyte(iobase + SMBUS_CONTROL_REG, offset);
+ __outbyte(iobase + SMBUS_HOST_CMD_REG, address);
+ __outbyte(iobase + SMBUS_COMMAND_REG, SMBUS_READ_BYTE_COMMAND);
+ } else {
+ /* Clear status, issue read command - auto increments to next byte */
+ __outbyte(iobase + SMBUS_STATUS_REG, 0x1E);
+ __outbyte(iobase + SMBUS_COMMAND_REG, SMBUS_READ_COMMAND);
+ }
+
+ /* time limit to avoid hanging for unexpected error status */
+ time_limit = __rdtsc() + MAX_READ_TSC_COUNT;
+ for (;;) {
+ status = __inbyte(iobase + SMBUS_STATUS_REG);
+ if (__rdtsc() > time_limit)
+ break;
+ if ((status & SMBUS_INTERRUPT_MASK) == 0)
+ continue; /* SMBusInterrupt not set, keep waiting */
+ if ((status & HOSTBUSY_MASK) != 0)
+ continue; /* HostBusy set, keep waiting */
+ break;
+ }
+
+ buffer[0] = __inbyte(iobase + SMBUS_DATA0_REG);
+ if (status == STATUS__COMPLETED_SUCCESSFULLY)
+ status = AGESA_SUCCESS;
+ else
+ status = AGESA_ERROR;
+
+ return status;
+}
+
+static void writePmReg(UINT8 reg, UINT8 data)
+{
+ __outbyte(PMIO_INDEX_REG, reg);
+ __outbyte(PMIO_DATA_REG, data);
+}
+
+static void setupFch(UINT16 ioBase)
+{
+ /* set up SMBUS - Set to SMBUS 0 & set base address */
+ /* For SB800 & Hudson1 to SB900 & Hudson 2/3 */
+ writePmReg(SMBUS_BAR_HIGH_BYTE, ioBase >> 8);
+ writePmReg(SMBUS_BAR_LOW_BYTE, (ioBase & 0xe0) | 1);
+
+ /* set SMBus clock to 400 KHz */
+ __outbyte(ioBase + SMBUS_CLOCK_REG, SMBUS_FREQUENCY_CONST / 400000);
+}
+
+/**
+ * Read one or more SPD bytes from a DIMM.
+ * Start with offset zero and read sequentially.
+ * Reads 128 bytes in 7-8 ms at 400 KHz.
+ */
+static UINT8 readspd(UINT16 iobase, UINT8 SmbusSlaveAddress, char *buffer,
+ UINT16 count)
+{
+ UINT16 index;
+ UINT8 status;
+
+ setupFch(iobase);
+
+ for (index = 0; index < count; index++) {
+ status = readSmbusByte(iobase, SmbusSlaveAddress, &buffer[index], index);
+ if (status != AGESA_SUCCESS)
+ return status;
+ }
+
+ return status;
+}
+
+/**
+ * Gets the SMBUS address for an SPD from the array in devicetree.cb
+ * then read the SPD into the supplied buffer.
+ */
+AGESA_STATUS agesa_ReadSPD(UINT32 unused1, UINT32 unused2, void *infoptr)
+{
+ UINT8 spdAddress;
+ UINT16 iobase = SMBUS0_BASE_ADDRESS;
+ AGESA_READ_SPD_PARAMS *info = infoptr;
+ ROMSTAGE_CONST struct device *dev = dev_find_slot(0, PCI_DEVFN(0x18, 2));
+ ROMSTAGE_CONST struct northbridge_amd_agesa_family14_config *config =
+ dev->chip_info;
+
+ if ((dev == 0) || (config == 0))
+ return AGESA_ERROR;
+
+ if (info->SocketId >= ARRAY_SIZE(config->spdAddrLookup))
+ return AGESA_ERROR;
+ if (info->MemChannelId >= ARRAY_SIZE(config->spdAddrLookup[0]))
+ return AGESA_ERROR;
+ if (info->DimmId >= ARRAY_SIZE(config->spdAddrLookup[0][0]))
+ return AGESA_ERROR;
+
+ spdAddress = config->spdAddrLookup
+ [info->SocketId][info->MemChannelId][info->DimmId];
+
+ if (spdAddress == 0)
+ return AGESA_ERROR;
+ return readspd(iobase, spdAddress, (void *)info->Buffer, 128);
+}
diff --git a/src/northbridge/amd/agesa/family14/dimmSpd.h b/src/northbridge/amd/agesa/family14/dimmSpd.h
new file mode 100644
index 0000000..57512c7
--- /dev/null
+++ b/src/northbridge/amd/agesa/family14/dimmSpd.h
@@ -0,0 +1,83 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA02110-1301 USA
+ */
+
+/*----------------------------------------------------------------------------------------
+ * M O D U L E S U S E D
+ *----------------------------------------------------------------------------------------
+ */
+
+#ifndef _DIMMSPD_H_
+#define _DIMMSPD_H_
+
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+#define READ_BIT 0x01
+
+#define SMBUS_INTERRUPT_MASK 0x02
+#define HOSTBUSY_MASK 0x01
+
+#define SMBUS_READ_BYTE_COMMAND 0x48
+#define SMBUS_READ_COMMAND 0x44
+
+#define MAX_READ_TSC_COUNT (2000000000 / 10)
+
+#define PMIO_INDEX_REG 0xCD6
+#define PMIO_DATA_REG 0xCD7
+
+#define SMBUS_BAR_LOW_BYTE 0x2C
+#define SMBUS_BAR_HIGH_BYTE 0x2D
+
+#define SMBUS_STATUS_REG 0x00
+#define SMBUS_SLAVE_STATUS_REG 0x01
+#define SMBUS_COMMAND_REG 0x02
+#define SMBUS_CONTROL_REG 0x03
+#define SMBUS_HOST_CMD_REG 0x04
+#define SMBUS_DATA0_REG 0x05
+#define SMBUS_CLOCK_REG 0x0E
+
+#define STATUS__COMPLETED_SUCCESSFULLY 0x02
+
+#define SMBUS_FREQUENCY_CONST 66000000 / 4
+/*----------------------------------------------------------------------------------------
+ * T Y P E D E F S A N D S T R U C T U R E S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * P R O T O T Y P E S O F L O C A L F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+/*----------------------------------------------------------------------------------------
+ * E X P O R T E D F U N C T I O N S
+ *----------------------------------------------------------------------------------------
+ */
+
+AGESA_STATUS
+agesa_ReadSPD (IN UINT32 Func, IN UINT32 Data, IN OUT void *SpdData);
+
+/*---------------------------------------------------------------------------------------
+ * L O C A L F U N C T I O N S
+ *---------------------------------------------------------------------------------------
+ */
+
+#endif