agesa: Add support for soldered down DDR3 initialization
Creates a new CONFIG_DDR3_SOLDERED_DOWN variable to enable handling proper DDR3 SPD initialization. This patch is from SageBIOS (forked coreboot) sources and is required for platforms such as the GizmoSphere Gizmo board. BUG=None BRANCH=none TEST=Run on Gizmo board and check SPD dump being same as SageBIOS Signed-off-by: Marcelo Povoa <marcelogp@chromium.org> Change-Id: I28e69d649252f542eb3d20d51ff8af69ae6e394a Reviewed-on: https://chromium-review.googlesource.com/188273 Reviewed-by: Stefan Reinauer <reinauer@chromium.org> Tested-by: Marcelo Póvoa <marcelogp@chromium.org> Commit-Queue: Marcelo Póvoa <marcelogp@chromium.org>
This commit is contained in:
parent
7d8570ac52
commit
b81b1bb51a
3 changed files with 150 additions and 0 deletions
|
|
@ -31,6 +31,10 @@ config S3_VGA_ROM_RUN
|
|||
bool
|
||||
default n
|
||||
|
||||
config DDR3_SOLDERED_DOWN
|
||||
bool
|
||||
default n
|
||||
|
||||
source src/northbridge/amd/agesa/family10/Kconfig
|
||||
source src/northbridge/amd/agesa/family12/Kconfig
|
||||
source src/northbridge/amd/agesa/family14/Kconfig
|
||||
|
|
|
|||
|
|
@ -29,9 +29,15 @@
|
|||
#include "dimmSpd.h"
|
||||
#include "chip.h"
|
||||
|
||||
#if CONFIG_DDR3_SOLDERED_DOWN
|
||||
#include CONFIG_PATH_TO_DDR3_SPD
|
||||
AGESA_STATUS calc_fake_spd_crc( UINT8 *SPDPtr, UINT16 *crc );
|
||||
#endif
|
||||
|
||||
/* uncomment for source level debug - GDB gets really confused otherwise. */
|
||||
//#pragma optimize ("", off)
|
||||
|
||||
#if !CONFIG_DDR3_SOLDERED_DOWN
|
||||
/**
|
||||
* Read a single SPD byte. If the first byte is being read, set up the
|
||||
* address and offset. Following bytes auto increment.
|
||||
|
|
@ -143,3 +149,71 @@ AGESA_STATUS agesa_ReadSPD(UINT32 unused1, UINT32 unused2, void *infoptr)
|
|||
return AGESA_ERROR;
|
||||
return readspd(SMBUS0_BASE_ADDRESS, spdAddress, (void *)info->Buffer, 128);
|
||||
}
|
||||
|
||||
#else // CONFIG_DDR3_SOLDERED_DOWN
|
||||
/*
|
||||
* Get the SPD from the mainboard
|
||||
*/
|
||||
AGESA_STATUS agesa_ReadSPD(UINT32 unused1, UINT32 unused2, void *infoptr)
|
||||
{
|
||||
UINT8 *spd_ptr;
|
||||
UINT16 index, crc;
|
||||
|
||||
AGESA_READ_SPD_PARAMS *info = infoptr;
|
||||
ROMSTAGE_CONST struct device *dev = dev_find_slot(0, PCI_DEVFN(0x18, 2));
|
||||
|
||||
if ((dev == 0) || (dev->chip_info == 0))
|
||||
return AGESA_ERROR;
|
||||
|
||||
if (info->MemChannelId > CONFIG_DDR3_CHANNEL_MAX) return AGESA_ERROR;
|
||||
if (info->SocketId != 0) return AGESA_ERROR;
|
||||
if (info->DimmId != 0) return AGESA_ERROR;
|
||||
|
||||
/* read the bytes from the table */
|
||||
spd_ptr = (UINT8 *)info->Buffer;
|
||||
for (index = 0; index < 128; index++)
|
||||
spd_ptr[index] = ddr3_fake_spd[index];
|
||||
|
||||
/* If CRC bytes are zeroes, calculate and store the CRC of the fake table */
|
||||
if ((spd_ptr[126] == 0) && (spd_ptr[127] == 0)) {
|
||||
calc_fake_spd_crc( spd_ptr, &crc );
|
||||
spd_ptr[126] = (UINT8)(crc & 0xFF);
|
||||
spd_ptr[127] = (UINT8)(crc>>8);
|
||||
}
|
||||
|
||||
/* print out the table */
|
||||
printk(BIOS_SPEW, "\nDump the fake SPD for Channel %d\n",info->MemChannelId);
|
||||
for (index = 0; index < 128; index++) {
|
||||
if((index&0x0F)==0x00) printk(BIOS_SPEW, "%02x: ",index);
|
||||
printk(BIOS_SPEW, "%02x ", spd_ptr[index]);
|
||||
if((index&0x0F)==0x0F) printk(BIOS_SPEW, "\n");
|
||||
}
|
||||
return AGESA_SUCCESS;
|
||||
}
|
||||
|
||||
AGESA_STATUS calc_fake_spd_crc( UINT8 *SPDPtr, UINT16 *crc )
|
||||
{
|
||||
INT16 i;
|
||||
INT16 j;
|
||||
INT16 jmax;
|
||||
|
||||
/* should the CRC be done on bytes 0-116 or 0-125 ? */
|
||||
if (SPDPtr[0] & 0x80)
|
||||
jmax = 117;
|
||||
else jmax = 126;
|
||||
|
||||
*crc = 0; /* zero out the CRC */
|
||||
|
||||
for (j = 0; j < jmax; j++) {
|
||||
*crc = *crc ^ ((UINT16)SPDPtr[j] << 8);
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (*crc & 0x8000) {
|
||||
*crc = (*crc << 1) ^ 0x1021;
|
||||
} else {
|
||||
*crc = (*crc << 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,9 +27,14 @@
|
|||
#include "dimmSpd.h"
|
||||
#include "chip.h"
|
||||
|
||||
#if CONFIG_DDR3_SOLDERED_DOWN
|
||||
#include CONFIG_PATH_TO_DDR3_SPD
|
||||
AGESA_STATUS calc_fake_spd_crc( UINT8 *SPDPtr, UINT16 *crc );
|
||||
#endif
|
||||
|
||||
#define DIMENSION(array)(sizeof (array)/ sizeof (array [0]))
|
||||
|
||||
#if !CONFIG_DDR3_SOLDERED_DOWN
|
||||
/*-----------------------------------------------------------------------------
|
||||
*
|
||||
* readSmbusByteData - read a single SPD byte from any offset
|
||||
|
|
@ -158,3 +163,70 @@ AGESA_STATUS AmdMemoryReadSPD (UINT32 unused1, UINT32 unused2, AGESA_READ_SPD_PA
|
|||
setupFch (ioBase);
|
||||
return readspd (ioBase, spdAddress, (void *) info->Buffer, 128);
|
||||
}
|
||||
|
||||
#else // CONFIG_DDR3_SOLDERED_DOWN
|
||||
/*
|
||||
* Get the SPD from the mainboard
|
||||
*/
|
||||
AGESA_STATUS AmdMemoryReadSPD (UINT32 unused1, UINT32 unused2, AGESA_READ_SPD_PARAMS *info)
|
||||
{
|
||||
UINT8 *spd_ptr;
|
||||
UINT16 index, crc;
|
||||
|
||||
ROMSTAGE_CONST struct device *dev = dev_find_slot(0, PCI_DEVFN(0x18, 2));
|
||||
|
||||
if ((dev == 0) || (dev->chip_info == 0))
|
||||
return AGESA_ERROR;
|
||||
|
||||
if (info->MemChannelId > CONFIG_DDR3_CHANNEL_MAX) return AGESA_ERROR;
|
||||
if (info->SocketId != 0) return AGESA_ERROR;
|
||||
if (info->DimmId != 0) return AGESA_ERROR;
|
||||
|
||||
/* read the bytes from the table */
|
||||
spd_ptr = (UINT8 *)info->Buffer;
|
||||
for (index = 0; index < 128; index++)
|
||||
spd_ptr[index] = ddr3_fake_spd[index];
|
||||
|
||||
/* If CRC bytes are zeroes, calculate and store the CRC of the fake table */
|
||||
if ((spd_ptr[126] == 0) && (spd_ptr[127] == 0)) {
|
||||
calc_fake_spd_crc( spd_ptr, &crc );
|
||||
spd_ptr[126] = (UINT8)(crc & 0xFF);
|
||||
spd_ptr[127] = (UINT8)(crc>>8);
|
||||
}
|
||||
|
||||
/* print out the table */
|
||||
printk(BIOS_SPEW, "\nDump the fake SPD for Channel %d\n",info->MemChannelId);
|
||||
for (index = 0; index < 128; index++) {
|
||||
if((index&0x0F)==0x00) printk(BIOS_SPEW, "%02x: ",index);
|
||||
printk(BIOS_SPEW, "%02x ", spd_ptr[index]);
|
||||
if((index&0x0F)==0x0F) printk(BIOS_SPEW, "\n");
|
||||
}
|
||||
return AGESA_SUCCESS;
|
||||
}
|
||||
|
||||
AGESA_STATUS calc_fake_spd_crc( UINT8 *SPDPtr, UINT16 *crc )
|
||||
{
|
||||
INT16 i;
|
||||
INT16 j;
|
||||
INT16 jmax;
|
||||
|
||||
/* should the CRC be done on bytes 0-116 or 0-125 ? */
|
||||
if (SPDPtr[0] & 0x80)
|
||||
jmax = 117;
|
||||
else jmax = 126;
|
||||
|
||||
*crc = 0; /* zero out the CRC */
|
||||
|
||||
for (j = 0; j < jmax; j++) {
|
||||
*crc = *crc ^ ((UINT16)SPDPtr[j] << 8);
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (*crc & 0x8000) {
|
||||
*crc = (*crc << 1) ^ 0x1021;
|
||||
} else {
|
||||
*crc = (*crc << 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue