A follow-up, for posterity:
I got the RCC-DFF from ADI to boot using the memory down option. To do this, I
enabled Memory Down in the FSP (via BCT) and also changed all of the SPD SMBus
Addresses to 0xff, to make sure the EEPROM wasn’t being used. Booting with
this FSP I get an expected “No DIMMs Present” error.
I then modified src/mainboard/adi/rcc-dff/romstage.c as attached, specifying
the SPD data from the Kingston datasheet and one populated DIMM on channel 0.
The RCC-DFF then booted normally.
As for our prototype, we got it to boot with one memory channel while ‘hot’.
We’re working with Intel to narrow it down, but it looks like a marginal trace
length issue. The verbose FSP tells us we are having issues during Command
Clock Training.
Thanks again for responses!
Andy
From: coreboot [mailto:[email protected]] On Behalf Of Andy Knowles
Sent: Monday, 23 January 2017 11:55
To: Agrain Patrick <[email protected]>
Cc: [email protected]
Subject: Re: [coreboot] Rangeley FSP reports "Err[24]: GetSet Value exceeds
limits" during memory init
This sender failed our fraud detection checks and may not be who they appear to
be. Learn about spoofing<http://aka.ms/LearnAboutSpoofing>
Feedback<http://aka.ms/SafetyTipsFeedback>
Hi Patrick,
I have an RCC-DFF from ADI. The memory is soldered down, but from their BIOS
source it seems they aren’t using the FSP memory down option, so I suspect they
have an EEPROM on the board with SPD data pretending to be a DIMM. I’m going to
try booting it with memory down set in FSP and SPD data in coreboot instead.
Thanks,
Andy
From: Agrain Patrick [mailto:[email protected]]
HI Andy,
RCC-VE dev board from ADI has also memory down. It may help to compare. But
unfortunately, schematics are not available.
Regards,
Patrick Agrain
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2010 coresystems GmbH
* Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
* Copyright (C) 2013-2014 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.
*/
#include <arch/io.h>
#include <device/pci_def.h>
#include <device/pnp_def.h>
#include <cpu/x86/lapic.h>
#include <drivers/intel/fsp1_0/fsp_util.h>
#include <southbridge/intel/fsp_rangeley/soc.h>
#include <southbridge/intel/fsp_rangeley/gpio.h>
#include <southbridge/intel/fsp_rangeley/romstage.h>
#include <arch/cpu.h>
#include "gpio.h"
static void interrupt_routing_config(void)
{
u8 *ilb_base = (u8 *)(pci_read_config32(SOC_LPC_DEV, IBASE) & ~0xf);
/*
* Initialize Interrupt Routings for each device in ilb_base_address.
* IR01 map to PCIe device 0x01 ... IR31 to device 0x1F.
* PIRQ_A maps to IRQ 16 ... PIRQ_H maps tp IRQ 23.
* This should match devicetree and the ACPI IRQ routing/
*/
write32(ilb_base + ILB_ACTL, 0x0000); /* ACTL bit 2:0 SCIS IRQ9 */
write16(ilb_base + ILB_IR01, 0x3210); /* IR01h IR(ABCD) - PIRQ(ABCD) */
write16(ilb_base + ILB_IR02, 0x3210); /* IR02h IR(ABCD) - PIRQ(ABCD) */
write16(ilb_base + ILB_IR03, 0x7654); /* IR03h IR(ABCD) - PIRQ(EFGH) */
write16(ilb_base + ILB_IR04, 0x7654); /* IR04h IR(ABCD) - PIRQ(EFGH) */
write16(ilb_base + ILB_IR20, 0x7654); /* IR14h IR(ABCD) - PIRQ(EFGH) */
write16(ilb_base + ILB_IR22, 0x0007); /* IR16h IR(A) - PIRQ(H) */
write16(ilb_base + ILB_IR23, 0x0003); /* IR17h IR(A) - PIRQ(D) */
write16(ilb_base + ILB_IR24, 0x0003); /* IR18h IR(A) - PIRQ(D) */
write16(ilb_base + ILB_IR31, 0x0020); /* IR1Fh IR(B) - PIRQ(C) */
}
/**
* /brief mainboard call for setup that needs to be done before fsp init
*
*/
void early_mainboard_romstage_entry(void)
{
setup_soc_gpios(&gpio_map);
}
/**
* /brief mainboard call for setup that needs to be done after fsp init
*
*/
void late_mainboard_romstage_entry(void)
{
interrupt_routing_config();
}
/**
* Get function disables - most of these will be done automatically
* @param mask pointer to the function-disable bitfield
*/
void get_func_disables(uint32_t *mask)
{
}
/*
* MEM_DOWN_DIMM_CONFIG
* MemoryDownDimmPopulation - 0: Empty 1: Populated.
* MemoryDownDimmSpdData - structure MEM_DOWN_DIMM_SPD_DATA for spd data.
*/
/* 4x Kingston 4Gb PC3-12800 DDR3-1600MHz Unbuffered CL11 Single Rank Memory
*/
static const MEM_DOWN_DIMM_CONFIG PopulatedDimm = {
0x01, // MemoryDownDimmPopulation
{ // MemoryDownDimmSpdData
0x0B, //Byte 2 Dram Device Type
DDR3
0x02, //Byte 3 Module type (3:0)
UDIMM (Unbuffered Long DIMM)
0x04, //Byte 4 Density and Banks
4Gb (8 Banks)
0x19, //Byte 5 Addressing
15 row x 10 col
0x02, //Byte 6 Nominal Voltage, VDD
1.35 V or 1.5 V
0x02, //Byte 7 Module Organization
1 Rank, 16 bit
0x03, //Byte 8 Memory Bus Width
64-bit
0x01, //Byte 10 Medium Timebase (MTB) Dividend
0.125 ns
0x08, //Byte 11 Medium Timebase (MTB) Divisor
0.125 ns
0x0A, //Byte 12 Minimum cycle time (tCKmin)
800 MHz (DDR1600)
0xFC, //Byte 14 CAS latency supported, low byte
CAS = 6 to 11
0x00, //Byte 15 CAS latency supported, high byte
No higher CAS
0x69, //Byte 16 Minimum CAS latency time (tAA)
tAAmin = 13.125 ns
0x78, //Byte 17 Minimum write recovery time (tWR)
tWR = 15 ns
0x69, //Byte 18 Minimum RAS to CAS time (tRCD)
tRCDmin = 13.125 ns
0x3C, //Byte 19 Minimum RA to RA time (tRRD)
tRRD = 7.5 ns
0x69, //Byte 20 Minimum precharge time (tRP)
tRPmin = 13.125 ns
0x11, //Byte 21 Upper nibbles for tRAS (7:4), tRC (3:0)
tRAS, tRC upper
0x18, //Byte 22 Minimum active to precharge (tRAS)
tRAS = 35 ns
0x86, //Byte 23 Minimum active to active/refresh (tRC)
tRC = 48.75 ns
0x20, //Byte 24 Minimum refresh recovery (tRFC), low byte
tRFC LSB
0x08, //Byte 25 Minimum refresh recovery (tRFC), high byte
0x820 tRFC = 260 ns
0x3C, //Byte 26 Minimum internal wr to rd cmd (tWTR)
tWTR = 7.5 ns
0x3C, //Byte 27 Minimum internal rd to pc cmd (tRTP)
tRTP = 7.5 ns
0x01, //Byte 28 Upper Nibble for tFAW
tFAW MSB
0x40, //Byte 29 Minimum Four Activate Window Delay Time (tFAWmin), LSB
tFAW = 40 ns
0x85, //Byte 31 SdramThermalRefreshOption
PASR + extended 2x
0x00, //Byte 32 ModuleThermalSensor
No thermal sensor
0x00, //Byte 33 SDRAM Device Type
Std Undefined
0x00, //Byte 34 Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
0x00, //Byte 35 Fine Offset for Minimum CAS Latency Time (tAAmin)
0x00, //Byte 41 Maximum Activate Count
Untested MAC
0x02, //Byte 62 Reference Raw Card Used
Ref raw card C
0x00, //Byte 63 Address Mapping from Edge Connector to DRAM
Standard
0x7F, //Byte 117 Module Manufacturer ID Code, Least Significant Byte
Kingston
0x98, //Byte 118 Module Manufacturer ID Code, Most Significant Byte
Kingston
0x00, //Byte 119 Module Manufacturing Location
0x00, //Byte 120 Module Manufacturing Date Year
0x00, //Byte 121 Module Manufacturing Date creation work week
0x00, //Byte 122 Module Serial Number A
0x00, //Byte 123 Module Serial Number B
0x00, //Byte 124 Module Serial Number C
0x00, //Byte 125 Module Serial Number D
0x7F, //Byte 148 DRAM Manufacturer ID Code, LSB
Kingston
0x98, //Byte 149 DRAM Manufacturer ID Code, MSB
Kingston
}
};
/* Dummy structure */
static const MEM_DOWN_DIMM_CONFIG UnpopulatedDimm = {
0x00, // MemoryDownDimmPopulation
{ // MemoryDownDimmSpdData
0, //Byte 2 Dram Device Type
0, //Byte 3 Module type (3:0)
0, //Byte 4 Density and Banks
0, //Byte 5 Addressing
0, //Byte 6 Nominal Voltage, VDD
0, //Byte 7 Module Organization
0, //Byte 8 Memory Bus Width
0, //Byte 10 Medium Timebase (MTB) Dividend
0, //Byte 11 Medium Timebase (MTB) Divisor
0, //Byte 12 Minimum cycle time (tCKmin)
0, //Byte 14 CAS latency supported, low byte
0, //Byte 15 CAS latency supported, high byte
0, //Byte 16 Minimum CAS latency time (tAA)
0, //Byte 17 Minimum write recovery time (tWR)
0, //Byte 18 Minimum RAS to CAS time (tRCD)
0, //Byte 19 Minimum RA to RA time (tRRD)
0, //Byte 20 Minimum precharge time (tRP)
0, //Byte 21 Upper nibbles for tRAS (7:4), tRC (3:0)
0, //Byte 22 Minimum active to precharge (tRAS)
0, //Byte 23 Minimum active to active/refresh (tRC)
0, //Byte 24 Minimum refresh recovery (tRFC), low byte
0, //Byte 25 Minimum refresh recovery (tRFC), high byte
0, //Byte 26 Minimum internal wr to rd cmd (tWTR)
0, //Byte 27 Minimum internal rd to pc cmd (tRTP)
0, //Byte 28 Upper Nibble for tFAW
0, //Byte 29 Minimum Four Activate Window Delay Time (tFAWmin), LSB
0, //Byte 31 SdramThermalRefreshOption
0, //Byte 32 ModuleThermalSensor
0, //Byte 33 SDRAM Device Type
0, //Byte 34 Fine Offset for SDRAM Minimum Cycle Time (tCKmin)
0, //Byte 35 Fine Offset for Minimum CAS Latency Time (tAAmin)
0, //Byte 41 Maximum Activate Count
0, //Byte 62 Reference Raw Card Used
0, //Byte 63 Address Mapping from Edge Connector to DRAM
0, //Byte 117 Module Manufacturer ID Code, Least Significant Byte
0, //Byte 118 Module Manufacturer ID Code, Most Significant Byte
0, //Byte 119 Module Manufacturing Location
0, //Byte 120 Module Manufacturing Date Year
0, //Byte 121 Module Manufacturing Date creation work week
0, //Byte 122 Module Serial Number A
0, //Byte 123 Module Serial Number B
0, //Byte 124 Module Serial Number C
0, //Byte 125 Module Serial Number D
0, //Byte 148 DRAM Manufacturer ID Code, LSB
0, //Byte 149 DRAM Manufacturer ID Code, MSB
}
};
void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer)
{
FspRtBuffer->Platform.MemDownDimmConfig[0][0] = (MEM_DOWN_DIMM_CONFIG
*)&PopulatedDimm; /* Channel0/Dimm0, DIMM populated */
FspRtBuffer->Platform.MemDownDimmConfig[0][1] = (MEM_DOWN_DIMM_CONFIG
*)&UnpopulatedDimm; /* Channel0/Dimm1, not populated */
FspRtBuffer->Platform.MemDownDimmConfig[1][0] = (MEM_DOWN_DIMM_CONFIG
*)&UnpopulatedDimm; /* Channel1/Dimm0, not populated */
FspRtBuffer->Platform.MemDownDimmConfig[1][1] = (MEM_DOWN_DIMM_CONFIG
*)&UnpopulatedDimm; /* Channel1/Dimm1, not populated */
return;
}
--
coreboot mailing list: [email protected]
https://www.coreboot.org/mailman/listinfo/coreboot