From bf13d3f567795324a587af745c71e58ce680ab3f Mon Sep 17 00:00:00 2001 From: Werner Zeh Date: Mon, 25 Apr 2016 12:24:17 +0200 Subject: mc_tcu3: Switch to hwilib instead of own hwinfo implementation Use hwilib in vendorcode/siemens/hwilib to get fields from hwinfo instead of having mainboard specific hwinfo code. This patch does not change the functional behavior in any way. Change-Id: Idb226a82a08b1b753f654c5cde106236e72f33c3 Signed-off-by: Werner Zeh Reviewed-on: https://review.coreboot.org/14506 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/mainboard/siemens/mc_tcu3/Kconfig | 1 + src/mainboard/siemens/mc_tcu3/Makefile.inc | 3 - src/mainboard/siemens/mc_tcu3/lcd_panel.c | 26 ++--- src/mainboard/siemens/mc_tcu3/mainboard.c | 40 ++++++- src/mainboard/siemens/mc_tcu3/modhwinfo.c | 144 ------------------------- src/mainboard/siemens/mc_tcu3/modhwinfo.h | 166 ----------------------------- src/mainboard/siemens/mc_tcu3/ptn3460.c | 49 ++++++--- src/mainboard/siemens/mc_tcu3/ptn3460.h | 3 +- src/mainboard/siemens/mc_tcu3/romstage.c | 65 ++++++----- 9 files changed, 120 insertions(+), 377 deletions(-) delete mode 100644 src/mainboard/siemens/mc_tcu3/modhwinfo.c delete mode 100644 src/mainboard/siemens/mc_tcu3/modhwinfo.h (limited to 'src/mainboard') diff --git a/src/mainboard/siemens/mc_tcu3/Kconfig b/src/mainboard/siemens/mc_tcu3/Kconfig index d7ff86756a..5ff233daa8 100644 --- a/src/mainboard/siemens/mc_tcu3/Kconfig +++ b/src/mainboard/siemens/mc_tcu3/Kconfig @@ -30,6 +30,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select USE_BLOBS select CBFS_AUTOGEN_ATTRIBUTES select FSP_BAYTRAIL_GFX_INIT + select USE_SIEMENS_HWILIB config MAINBOARD_DIR string diff --git a/src/mainboard/siemens/mc_tcu3/Makefile.inc b/src/mainboard/siemens/mc_tcu3/Makefile.inc index 12be6a703a..2922eef9da 100644 --- a/src/mainboard/siemens/mc_tcu3/Makefile.inc +++ b/src/mainboard/siemens/mc_tcu3/Makefile.inc @@ -13,11 +13,8 @@ ## GNU General Public License for more details. ## -romstage-y += modhwinfo.c - ramstage-y += gpio.c ramstage-y += irqroute.c -ramstage-y += modhwinfo.c ramstage-y += lcd_panel.c ramstage-y += ptn3460.c diff --git a/src/mainboard/siemens/mc_tcu3/lcd_panel.c b/src/mainboard/siemens/mc_tcu3/lcd_panel.c index 91159f98d2..214773aa26 100644 --- a/src/mainboard/siemens/mc_tcu3/lcd_panel.c +++ b/src/mainboard/siemens/mc_tcu3/lcd_panel.c @@ -15,11 +15,11 @@ #include #include #include -#include "modhwinfo.h" #include "soc/gpio.h" #include "lcd_panel.h" #include "ptn3460.h" + /** \brief Reads GPIOs used for LCD panel encoding and returns the 4 bit value * @param no parameters * @return LCD panel type encoded in 4 bits @@ -42,10 +42,8 @@ u8 get_lcd_panel_type(void) */ int setup_lcd_panel(void) { - u8 lcd_type; + u8 lcd_type; int status; - struct edidinfo *eib = NULL; - struct shortinfo *sib = NULL; char blockname[33]; lcd_type = get_lcd_panel_type(); @@ -71,20 +69,12 @@ int setup_lcd_panel(void) status = 1; break; } - - /* Now that we have the panel type, get the matching block and setup */ - /* the DP2LVDS converter accordingly */ - eib = get_edidinfo(blockname); - sib = get_shortinfo(blockname); - - if ((!eib) || (!sib)) { - printk(BIOS_ERR, "LCD: Info block named \"%s\" not found!\n", blockname); - status = 1; - } else { - printk(BIOS_INFO, "LCD: Found SIB at 0x%x, EIB at 0x%x\n", - (int)sib, (int)eib); - status = ptn3460_init(lcd_type, eib, sib); + /* Now that we have the panel type, setup the DP2LVDS converter */ + status = ptn3460_init(blockname); + if (status) + printk(BIOS_ERR, "LCD: Setup PTN with status 0x%x\n", status); + else printk(BIOS_INFO, "LCD: Setup PTN with status 0x%x\n", status); - } + return status; } diff --git a/src/mainboard/siemens/mc_tcu3/mainboard.c b/src/mainboard/siemens/mc_tcu3/mainboard.c index 8a966dcc84..e9c29a07b5 100644 --- a/src/mainboard/siemens/mc_tcu3/mainboard.c +++ b/src/mainboard/siemens/mc_tcu3/mainboard.c @@ -29,9 +29,47 @@ #include #include #include - +#include #include "lcd_panel.h" + +/** \brief This function will search for a MAC address which can be assigned + * to a MACPHY. + * @param pci_bdf Bus, device and function of the given PCI-device + * @param mac buffer where to store the MAC address + * @return cb_err CB_ERR or CB_SUCCESS + */ +enum cb_err mainboard_get_mac_address(u16 bus, u8 devfn, u8 mac[6]) +{ + uint8_t mac_adr[6]; + u32 i; + + /* Open main hwinfo block */ + if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS) + return CB_ERR; + /* Get first MAC address from hwinfo. */ + if (hwilib_get_field(Mac1, mac_adr, sizeof(mac_adr)) != sizeof(mac_adr)) + return CB_ERR; + /* Ensure the first MAC-Address is not completely 0x00 or 0xff */ + for (i = 0; i < 6; i++) { + if (mac_adr[i] != 0xFF) + break; + } + if (i == 6){ + return CB_ERR; + } + for (i = 0; i < 6; i++) { + if (mac_adr[i] != 0x00) + break; + } + if (i == 6){ + return CB_ERR; + } else { + memcpy(mac, mac_adr, 6); + return CB_SUCCESS; + } +} + /* * mainboard_enable is executed as first thing after enumerate_buses(). * This is the earliest point to add customization. diff --git a/src/mainboard/siemens/mc_tcu3/modhwinfo.c b/src/mainboard/siemens/mc_tcu3/modhwinfo.c deleted file mode 100644 index ac7404b4fb..0000000000 --- a/src/mainboard/siemens/mc_tcu3/modhwinfo.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Siemens AG. - * - * 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 "modhwinfo.h" -#include "lcd_panel.h" -#include -#include - -/** \brief This function will find the first linked info block. - * @param *filename Filename in cbfs - * @param *file_offset Pointer to the offset of the cbfs file contents - * @return u8* Pointer to the found block - */ -u8* get_first_linked_block(char *filename, u8 **file_offset) -{ - u8* block_ptr = NULL; - - block_ptr = cbfs_boot_map_with_leak(filename, 0x50, NULL); - if (!block_ptr) - return NULL; - if (!strncmp((char*)block_ptr, "H1W2M3I4", LEN_MAGIC_NUM)) { - if ((*((u16*)(block_ptr + HWI_LEN_OFFSET)) == LEN_MAIN_HWINFO) && - (*((s32*)(block_ptr + NEXT_OFFSET_HWINFO)) != 0x00)) { - *file_offset = block_ptr; - return *((s32*)(block_ptr + NEXT_OFFSET_HWINFO)) + block_ptr; - } else - return NULL; - } else if (!strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM)) { - *file_offset = block_ptr; - return block_ptr; - } else - return NULL; -} - -/** \brief This function will find the main info block - * @param *filename Filename in cbfs - * @return *hwinfo Pointer to the data of the main info block - */ -struct hwinfo* get_hwinfo(char *filename) -{ - struct hwinfo* main_hwinfo; - - main_hwinfo = cbfs_boot_map_with_leak(filename, 0x50, NULL); - if ((main_hwinfo) && - (!strncmp(main_hwinfo->magicNumber, "H1W2M3I4", LEN_MAGIC_NUM)) && - (main_hwinfo->length == LEN_MAIN_HWINFO)) - return main_hwinfo; - else - return NULL; -} - -/** \brief This function will find the short info block - * @param *filename Filename in cbfs - * @return *shortinfo Pointer to the data of the short info block - */ -struct shortinfo* get_shortinfo(char *filename) -{ - u8 *block_ptr = NULL; - u8 *file_offset = NULL; - - block_ptr = get_first_linked_block(filename, &file_offset); - if ((block_ptr == NULL) || - (strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM))) - return NULL; - - if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_SHORT_INFO) - return (struct shortinfo *)block_ptr; - - block_ptr = (file_offset + *((s32*)(block_ptr + NEXT_OFFSET_EDID))); - if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_SHORT_INFO) - return (struct shortinfo *)block_ptr; - else - return NULL; -} - -/** \brief This function will find the edid info block - * @param *filename Filename in cbfs - * @return *edidinfo Pointer to the data of the edid info block - */ -struct edidinfo* get_edidinfo(char *filename) -{ - u8 *block_ptr = NULL; - u8 *file_offset = NULL; - - block_ptr = get_first_linked_block(filename, &file_offset); - if ((block_ptr == NULL) || - (strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM))) - return NULL; - - if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_EDID_INFO) - return (struct edidinfo *)block_ptr; - - block_ptr = (file_offset + *((s32*)(block_ptr + NEXT_OFFSET_SIB))); - if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_EDID_INFO) - return (struct edidinfo *)block_ptr; - else - return NULL; -} - -/** \brief This function will search for a MAC address which can be assigned - * to a MACPHY. - * @param pci_bdf Bus, device and function of the given PCI-device - * @param mac buffer where to store the MAC address - * @return cb_err CB_ERR or CB_SUCCESS - */ -enum cb_err mainboard_get_mac_address(u16 bus, u8 devfn, u8 mac[6]) -{ - struct hwinfo* main_hwinfo; - u32 i; - - main_hwinfo = get_hwinfo((char*)"hwinfo.hex"); - if (!main_hwinfo) - return CB_ERR; - /* Ensure the first MAC-Address is not completely 0x00 or 0xff */ - for (i = 0; i < 6; i++) { - if (main_hwinfo->macAddress1[i] != 0xFF) - break; - } - if (i == 6){ - return CB_ERR; - } - for (i = 0; i < 6; i++) { - if (main_hwinfo->macAddress1[i] != 0x00) - break; - } - if (i == 6){ - return CB_ERR; - } else { - memcpy(mac, main_hwinfo->macAddress1, 6); - return CB_SUCCESS; - } -} diff --git a/src/mainboard/siemens/mc_tcu3/modhwinfo.h b/src/mainboard/siemens/mc_tcu3/modhwinfo.h deleted file mode 100644 index 6bf891c875..0000000000 --- a/src/mainboard/siemens/mc_tcu3/modhwinfo.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Siemens AG - * - * 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. - */ - -#ifndef _MODHWINFO_H_ -#define _MODHWINFO_H_ - -#include - -#define LEN_MAGIC_NUM 8 -#define LEN_MLFB 20 -#define LEN_SERIAL_NUM 16 -#define LEN_HW_REVISION 2 -#define LEN_MAC_ADDRESS 6 -#define LEN_SPD 128 -#define NUMBER_OF_MAC_ADDR 4 -#define LEN_EDID 128 -#define LEN_MAIN_HWINFO 509 -#define LEN_SHORT_INFO 289 -#define LEN_EDID_INFO 181 -#define NEXT_OFFSET_HWINFO 476 -#define NEXT_OFFSET_SIB 260 -#define NEXT_OFFSET_EDID 176 -#define HWI_LEN_OFFSET 12 - -/* Define some masks and values */ -#define SIB_HWINIT_IDX 0x0e -#define SIB_COLOR_6BIT 0x00 -#define SIB_COLOR_8BIT 0x01 -#define SIB_COLOR_10BIT 0x02 -#define SIB_DISP_CON_IDX 0x16 -#define SIB_LVDS_SINGLE_LANE 0x00 -#define SIB_LVDS_DUAL_LANE 0x05 - -struct PhysDevStruc { - u8 bustype; - u8 devfn; - u16 bus; -} __attribute__ ((packed)); - - -struct hwinfo { -// Offset 0x0 - char magicNumber[LEN_MAGIC_NUM]; -// Offset 0x08 - u8 versionID[4]; -// Offset 0x0c - u16 length; -// Offset 0x0e - char BGR_Name[128]; -//Offset 0x8e - char MLFB[LEN_MLFB]; -// Offset 0xa2 - u8 uniqueNumber[16]; -// Offset 0xb2 - u8 fill_1[12]; -// Offset 0xbe - u8 hwRevision[LEN_HW_REVISION]; -//Offset 0xc0 - u8 macAddress1[LEN_MAC_ADDRESS]; - u8 numOfAuxMacAddr1; - u8 fill_2; -//Offset 0xc8 - u8 macAddress2[LEN_MAC_ADDRESS]; - u8 numOfAuxMacAddr2; - u8 fill_3; -//Offset 0xd0 - u8 macAddress3[LEN_MAC_ADDRESS]; - u8 numOfAuxMacAddr3; - u8 fill_4; -//Offset 0xd8 - u8 macAddress4[LEN_MAC_ADDRESS]; - u8 numOfAuxMacAddr4; - u8 fill_5; -// Offset 0xe0 - u8 SPD[LEN_SPD]; -// Offset 0x160 - u8 fill_6[88]; -// Offset 0x1b8 - u32 featureFlags; -// Offset 0x1bc - u8 fill_7[4]; -// Offset 0x1c0 - u32 biosFlags; -// Offset 0x1c4 - u8 fill_8[8]; -//Offset 0x1cc - struct PhysDevStruc etherDev[NUMBER_OF_MAC_ADDR]; -// Offset 0x1dc - s32 nextInfoOffset; -// Offset 0x1e0 - u8 fill_9[4]; -// Offset 0x1e4 - u32 portRTC; -// Offset 0x1e8 - u8 typeRTC; -// Offset 0x1e9 - u8 fill_10[20]; -} __attribute__ ((packed)); - -struct shortinfo { -// Offset 0x0 - char magicNumber[LEN_MAGIC_NUM]; -// Offset 0x08 - u8 versionID[4]; -// Offset 0x0c - u16 length; -// Offset 0x0e - char BGR_Name[128]; -//Offset 0x8e - char MLFB[LEN_MLFB]; -// Offset 0xa2 - u8 uniqueNumber[26]; -// Offset 0xbc - u8 fill_1[12]; -//Offset 0xc8 - u8 hwRevision[2]; -// Offset 0xca - u8 fill_2[18]; -// Offset 0xdc - u8 panelFeatures[32]; -// Offset 0xfc - u8 fill_3[8]; -// Offset 0x104 - s32 nextInfoOffset; -// Offset 0x108 - u8 fill_4[25]; -} __attribute__ ((packed)); - -struct edidinfo { -// Offset 0x0 - char magicNumber[LEN_MAGIC_NUM]; -// Offset 0x08 - u8 versionID[4]; -// Offset 0x0c - u16 length; -// Offset 0x0e - u8 fill_1[2]; -// Offset 0x10 - u8 edid[LEN_EDID]; -// Offset 0x90 - u8 fill_2[32]; -// Offset 0xb0 - s32 nextInfoOffset; -// Offset 0xb4 - u8 fill_3; -} __attribute__ ((packed)); - -u8* get_first_linked_block(char *filename, u8 **starting_adr); -struct hwinfo* get_hwinfo(char *filename); -struct shortinfo* get_shortinfo(char *filename); -struct edidinfo* get_edidinfo(char *filename); -enum cb_err mainboard_get_mac_address(u16 bus, u8 devfn, u8 mac[6]); - -#endif /* _MODHWINFO_H_ */ diff --git a/src/mainboard/siemens/mc_tcu3/ptn3460.c b/src/mainboard/siemens/mc_tcu3/ptn3460.c index e371e53c7f..21847bd275 100644 --- a/src/mainboard/siemens/mc_tcu3/ptn3460.c +++ b/src/mainboard/siemens/mc_tcu3/ptn3460.c @@ -14,33 +14,52 @@ */ #include +#include #include "soc/i2c.h" #include "ptn3460.h" /** \brief This functions sets up the DP2LVDS-converter to be used with the * appropriate lcd panel - * @param lcd_type Type of LCD we should set up the converter for - * @param *sib Pointer to short info block structure - * @param *eib Pointer to EDID info block structure - * @return 0 on success or error code + * @param *hwi_block Filename in CBFS of the block to use as HW-Info + * @return 0 on success or error code */ -int ptn3460_init(char lcd_type, struct edidinfo *eib, struct shortinfo *sib) +int ptn3460_init(char *hwi_block) { struct ptn_3460_config cfg; int status; + uint8_t disp_con = 0, color_depth = 0; + uint8_t edid_data[0x80]; + if (!hwi_block || hwilib_find_blocks(hwi_block) != CB_SUCCESS) { + printk(BIOS_ERR, "LCD: Info block \"%s\" not found!\n", + hwi_block); + return 1; + } status = i2c_init(PTN_I2C_CONTROLER); if (status) return (PTN_BUS_ERROR | status); - /* If we are here, we have all the desired information for setting up */ - /* DP2LVDS converter. In addition, the information matches the connected */ - /* LCD-panel and therefore, we do not have to distinguish between */ - /* different panels here for the timing. Inside the converter, table 6 */ - /* will be used for the timings. */ - status = ptn3460_write_edid(6, eib->edid); - if (status) + /* Get all needed information from hwinfo block */ + if (hwilib_get_field(Edid, edid_data, 0x80) != sizeof(edid_data)) { + printk(BIOS_ERR, "LCD: No EDID data available in %s\n", + hwi_block); + return 1; + } + if ((hwilib_get_field(PF_DisplCon, &disp_con, 1) != 1)) { + printk(BIOS_ERR, "LCD: Missing panel features from %s\n", + hwi_block); + return 1; + } + if (hwilib_get_field(PF_Color_Depth ,&color_depth, 1) != 1) { + printk(BIOS_ERR, "LCD: Missing panel features from %s\n", + hwi_block); + return 1; + } + /* Here, all the desired information for setting up DP2LVDS converter*/ + /* are present. Inside the converter, table 6 will be used for */ + /* the timings. */ + if ((status = ptn3460_write_edid(6, edid_data)) != 0) return status; /* Select this table to be emulated */ ptn_select_edid(6); @@ -50,12 +69,12 @@ int ptn3460_init(char lcd_type, struct edidinfo *eib, struct shortinfo *sib) if (status) return (PTN_BUS_ERROR | status); - /* Set up configuration data according to the information blocks we get */ + /* Set up configuration data according to the hwinfo blocks we get */ cfg.dp_interface_ctrl = 0; cfg.lvds_interface_ctrl1 = 0x00; - if (sib->panelFeatures[SIB_DISP_CON_IDX] == SIB_LVDS_DUAL_LANE) + if (disp_con == PF_DISPLCON_LVDS_DUAL) cfg.lvds_interface_ctrl1 |= 0x0b; /* Turn on dual LVDS lane and clock */ - if ((sib->panelFeatures[SIB_HWINIT_IDX] & 0x03) == SIB_COLOR_6BIT) + if (color_depth == PF_COLOR_DEPTH_6BIT) cfg.lvds_interface_ctrl1 |= 0x20; /* Use 18 bits per pixel */ cfg.lvds_interface_ctrl2 = 0x03; /* no clock spreading, 300 mV LVDS swing */ diff --git a/src/mainboard/siemens/mc_tcu3/ptn3460.h b/src/mainboard/siemens/mc_tcu3/ptn3460.h index 3e0c065a65..533607c194 100644 --- a/src/mainboard/siemens/mc_tcu3/ptn3460.h +++ b/src/mainboard/siemens/mc_tcu3/ptn3460.h @@ -17,7 +17,6 @@ #define PTN3460_H_ #include -#include "modhwinfo.h" #include "lcd_panel.h" #define PTN_SLAVE_ADR 0x20 @@ -66,7 +65,7 @@ struct ptn_3460_flash{ }__attribute__((packed)); -int ptn3460_init(char lcd_type, struct edidinfo *eib, struct shortinfo *sib); +int ptn3460_init(char *hwi_block); int ptn3460_read_edid(u8 edid_num, u8 *data); int ptn3460_write_edid(u8 edid_num, u8 *data); int ptn_select_edid(u8 edid_num); diff --git a/src/mainboard/siemens/mc_tcu3/romstage.c b/src/mainboard/siemens/mc_tcu3/romstage.c index 1fa78ca3da..c8cc66b49e 100644 --- a/src/mainboard/siemens/mc_tcu3/romstage.c +++ b/src/mainboard/siemens/mc_tcu3/romstage.c @@ -33,7 +33,7 @@ #include #include #include -#include "modhwinfo.h" +#include /** * /brief mainboard call for setup that needs to be done before fsp init @@ -166,35 +166,44 @@ const PCH_AZALIA_CONFIG mainboard_AzaliaConfig = { */ void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer) { - struct hwinfo *hwi_main; + uint8_t spd[0x80]; UPD_DATA_REGION *UpdData = FspRtBuffer->Common.UpdDataRgnPtr; - /* Initialize the Azalia Verb Tables to mainboard specific version */ + /* Initialize the Azalia Verb Tables to mainboard specific version. */ UpdData->AzaliaConfigPtr = (UINT32)&mainboard_AzaliaConfig; - /* Get SPD data from hardware information block and setup memory down */ - /* parameters for FSP accordingly */ - hwi_main = get_hwinfo((char*)"hwinfo.hex"); - if (hwi_main) { - UpdData->PcdMemoryParameters.EnableMemoryDown = 1; - UpdData->PcdMemoryParameters.DRAMType = hwi_main->SPD[2]; - UpdData->PcdMemoryParameters.DIMM0Enable = hwi_main->SPD[3] & 0x01; - UpdData->PcdMemoryParameters.DIMM1Enable = (hwi_main->SPD[3] >> 1) & 0x01; - UpdData->PcdMemoryParameters.DIMMDensity = hwi_main->SPD[4]; - UpdData->PcdMemoryParameters.DIMMDWidth = hwi_main->SPD[5]; - UpdData->PcdMemoryParameters.DIMMSides = hwi_main->SPD[7]; - UpdData->PcdMemoryParameters.DIMMBusWidth = hwi_main->SPD[8]; - UpdData->PcdMemoryParameters.DRAMSpeed = hwi_main->SPD[12]; - UpdData->PcdMemoryParameters.DIMMtCL = hwi_main->SPD[14]; - UpdData->PcdMemoryParameters.DIMMtWR = hwi_main->SPD[17]; - UpdData->PcdMemoryParameters.DIMMtRPtRCD = hwi_main->SPD[18]; - UpdData->PcdMemoryParameters.DIMMtRRD = hwi_main->SPD[19]; - UpdData->PcdMemoryParameters.DIMMtWTR = hwi_main->SPD[26]; - UpdData->PcdMemoryParameters.DIMMtRTP = hwi_main->SPD[27]; - UpdData->PcdMemoryParameters.DIMMtFAW = hwi_main->SPD[28]; - /*If one need output from MRC to be used in Intel RMT, simply */ - /*enable the following line */ - //UpdData->PcdMrcDebugMsg = 1; - } else - printk(BIOS_ERR, "HWInfo not found, leave default timings for DDR3.\n"); + /* Get SPD data from hwinfo block and set up memory down */ + /* parameters for FSP accordingly. */ + if (hwilib_find_blocks("hwinfo.hex")) { + printk(BIOS_ERR, + "HWInfo not found, use default timings for DDR3.\n"); + return; + } + + if (hwilib_get_field(SPD, spd, sizeof(spd)) != sizeof(spd)) { + printk(BIOS_ERR, + "SPD not found in HWInfo, use defaults for DDR3.\n"); + return; + } + /*Set up DDR timings from HWInfo. */ + UpdData->PcdMemoryParameters.EnableMemoryDown = 1; + UpdData->PcdMemoryParameters.DRAMType = spd[2]; + UpdData->PcdMemoryParameters.DIMM0Enable = spd[3] & 0x01; + UpdData->PcdMemoryParameters.DIMM1Enable = (spd[3] >> 1) & 0x01; + UpdData->PcdMemoryParameters.DIMMDensity = spd[4]; + UpdData->PcdMemoryParameters.DIMMDWidth = spd[5]; + UpdData->PcdMemoryParameters.DIMMSides = spd[7]; + UpdData->PcdMemoryParameters.DIMMBusWidth = spd[8]; + UpdData->PcdMemoryParameters.DRAMSpeed = spd[12]; + UpdData->PcdMemoryParameters.DIMMtCL = spd[14]; + UpdData->PcdMemoryParameters.DIMMtWR = spd[17]; + UpdData->PcdMemoryParameters.DIMMtRPtRCD = spd[18]; + UpdData->PcdMemoryParameters.DIMMtRRD = spd[19]; + UpdData->PcdMemoryParameters.DIMMtWTR = spd[26]; + UpdData->PcdMemoryParameters.DIMMtRTP = spd[27]; + UpdData->PcdMemoryParameters.DIMMtFAW = spd[28]; + + /*If one need output from MRC to be used in Intel RMT, simply */ + /*enable the following line */ + //UpdData->PcdMrcDebugMsg = 1; } -- cgit v1.2.3