From ab5d6902fdef7c7f26145619030a42aeda24b1ab Mon Sep 17 00:00:00 2001 From: Naresh G Solanki Date: Sat, 15 Oct 2016 18:13:55 +0530 Subject: mainboard/intel/kblrvp: Initial commit for Intel Kaby Lake RVP3 Add support for Kaby Lake RVP3. Use kunimitsu at commit 028200f as base. Kabylake RVP3 is based on Kabylake-Y with onboard Dual Channel LPDDR3 DIMM. * Update board name to kblrvp * Remove fsp 1.1 specific code( As Kabylake uses fsp2.0) * Remove board id function. * Remove unused spd & add rvp3 spd file. This is an initial commit does not have full support to boot. Will add more CLs to boot Chrome OS with depthcharge. Change-Id: Id8e32c5b93fc32ba84278c5c5da8f8e30c201bea Signed-off-by: Naresh G Solanki Reviewed-on: https://review.coreboot.org/17032 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/mainboard/intel/kblrvp/spd/Makefile.inc | 51 ++++++++++++ src/mainboard/intel/kblrvp/spd/empty.spd.hex | 16 ++++ src/mainboard/intel/kblrvp/spd/rvp3.spd.hex | 16 ++++ src/mainboard/intel/kblrvp/spd/spd.c | 93 +++++++++++++++++++++ src/mainboard/intel/kblrvp/spd/spd.h | 63 ++++++++++++++ src/mainboard/intel/kblrvp/spd/spd_util.c | 118 +++++++++++++++++++++++++++ 6 files changed, 357 insertions(+) create mode 100644 src/mainboard/intel/kblrvp/spd/Makefile.inc create mode 100644 src/mainboard/intel/kblrvp/spd/empty.spd.hex create mode 100644 src/mainboard/intel/kblrvp/spd/rvp3.spd.hex create mode 100644 src/mainboard/intel/kblrvp/spd/spd.c create mode 100644 src/mainboard/intel/kblrvp/spd/spd.h create mode 100644 src/mainboard/intel/kblrvp/spd/spd_util.c (limited to 'src/mainboard/intel/kblrvp/spd') diff --git a/src/mainboard/intel/kblrvp/spd/Makefile.inc b/src/mainboard/intel/kblrvp/spd/Makefile.inc new file mode 100644 index 0000000000..77dd16a2fc --- /dev/null +++ b/src/mainboard/intel/kblrvp/spd/Makefile.inc @@ -0,0 +1,51 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2014 Google Inc. +## Copyright (C) 2015 Intel Corporation. +## +## 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. +## + +romstage-y += spd_util.c + +SPD_BIN = $(obj)/spd.bin + +SPD_SOURCES = rvp3 # 0b0000 Dual Channel 4GB +SPD_SOURCES += empty +SPD_SOURCES += empty +SPD_SOURCES += empty +SPD_SOURCES += empty +SPD_SOURCES += empty +SPD_SOURCES += empty +SPD_SOURCES += empty +SPD_SOURCES += empty +SPD_SOURCES += empty +SPD_SOURCES += empty +SPD_SOURCES += empty +SPD_SOURCES += empty +SPD_SOURCES += empty +SPD_SOURCES += empty +SPD_SOURCES += empty + + +SPD_DEPS := $(foreach f, $(SPD_SOURCES), src/mainboard/$(MAINBOARDDIR)/spd/$(f).spd.hex) + +# Include spd ROM data +$(SPD_BIN): $(SPD_DEPS) + for f in $+; \ + do for c in $$(cat $$f | grep -v ^#); \ + do printf $$(printf '\%o' 0x$$c); \ + done; \ + done > $@ + +cbfs-files-y += spd.bin +spd.bin-file := $(SPD_BIN) +spd.bin-type := spd diff --git a/src/mainboard/intel/kblrvp/spd/empty.spd.hex b/src/mainboard/intel/kblrvp/spd/empty.spd.hex new file mode 100644 index 0000000000..9ec39f1ba4 --- /dev/null +++ b/src/mainboard/intel/kblrvp/spd/empty.spd.hex @@ -0,0 +1,16 @@ +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/intel/kblrvp/spd/rvp3.spd.hex b/src/mainboard/intel/kblrvp/spd/rvp3.spd.hex new file mode 100644 index 0000000000..e032411713 --- /dev/null +++ b/src/mainboard/intel/kblrvp/spd/rvp3.spd.hex @@ -0,0 +1,16 @@ +24 20 F1 0E 14 11 95 00 00 00 00 03 0B 23 00 00 +00 00 0A FF 54 00 00 00 78 00 90 A8 90 10 04 E0 +01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 7F 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 \ No newline at end of file diff --git a/src/mainboard/intel/kblrvp/spd/spd.c b/src/mainboard/intel/kblrvp/spd/spd.c new file mode 100644 index 0000000000..fe30621316 --- /dev/null +++ b/src/mainboard/intel/kblrvp/spd/spd.c @@ -0,0 +1,93 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. + * + * 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 +#include +#include +#include +#include +#include + +#include "spd.h" + +static void mainboard_print_spd_info(uint8_t spd[]) +{ + const int spd_banks[8] = { 8, 16, 32, 64, -1, -1, -1, -1 }; + const int spd_capmb[8] = { 1, 2, 4, 8, 16, 32, 64, 0 }; + const int spd_rows[8] = { 12, 13, 14, 15, 16, -1, -1, -1 }; + const int spd_cols[8] = { 9, 10, 11, 12, -1, -1, -1, -1 }; + const int spd_ranks[8] = { 1, 2, 3, 4, -1, -1, -1, -1 }; + const int spd_devw[8] = { 4, 8, 16, 32, -1, -1, -1, -1 }; + const int spd_busw[8] = { 8, 16, 32, 64, -1, -1, -1, -1 }; + char spd_name[SPD_PART_LEN+1] = { 0 }; + + int banks = spd_banks[(spd[SPD_DENSITY_BANKS] >> 4) & 7]; + int capmb = spd_capmb[spd[SPD_DENSITY_BANKS] & 7] * 256; + int rows = spd_rows[(spd[SPD_ADDRESSING] >> 3) & 7]; + int cols = spd_cols[spd[SPD_ADDRESSING] & 7]; + int ranks = spd_ranks[(spd[SPD_ORGANIZATION] >> 3) & 7]; + int devw = spd_devw[spd[SPD_ORGANIZATION] & 7]; + int busw = spd_busw[spd[SPD_BUS_DEV_WIDTH] & 7]; + + /* Module type */ + printk(BIOS_INFO, "SPD: module type is "); + switch (spd[SPD_DRAM_TYPE]) { + case SPD_DRAM_DDR3: + printk(BIOS_INFO, "DDR3\n"); + break; + case SPD_DRAM_LPDDR3: + printk(BIOS_INFO, "LPDDR3\n"); + break; + default: + printk(BIOS_INFO, "Unknown (%02x)\n", spd[SPD_DRAM_TYPE]); + break; + } + + /* Module Part Number */ + memcpy(spd_name, &spd[SPD_PART_OFF], SPD_PART_LEN); + spd_name[SPD_PART_LEN] = 0; + printk(BIOS_INFO, "SPD: module part is %s\n", spd_name); + + printk(BIOS_INFO, + "SPD: banks %d, ranks %d, rows %d, columns %d, density %d Mb\n", + banks, ranks, rows, cols, capmb); + printk(BIOS_INFO, "SPD: device width %d bits, bus width %d bits\n", + devw, busw); + + if (capmb > 0 && busw > 0 && devw > 0 && ranks > 0) { + /* SIZE = DENSITY / 8 * BUS_WIDTH / SDRAM_WIDTH * RANKS */ + printk(BIOS_INFO, "SPD: module size is %u MB (per channel)\n", + capmb / 8 * busw / devw * ranks); + } +} + +/* Copy SPD data for on-board memory */ +void mainboard_fill_spd_data(struct pei_data *pei_data) +{ + uintptr_t spd_data; + spd_data = mainboard_get_spd_data(); + + memcpy(pei_data->spd_data[0][0], (void *)spd_data, SPD_LEN); + + if (mainboard_has_dual_channel_mem()) + memcpy(pei_data->spd_data[1][0], (void *)spd_data, SPD_LEN); + + /* Make sure a valid SPD was found */ + if (pei_data->spd_data[0][0][0] == 0) + die("Invalid SPD data."); + + mainboard_print_spd_info(pei_data->spd_data[0][0]); +} diff --git a/src/mainboard/intel/kblrvp/spd/spd.h b/src/mainboard/intel/kblrvp/spd/spd.h new file mode 100644 index 0000000000..e04d13c3fb --- /dev/null +++ b/src/mainboard/intel/kblrvp/spd/spd.h @@ -0,0 +1,63 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. + * + * 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 MAINBOARD_SPD_H + +#include +#include "../gpio.h" + +#define MAINBOARD_SPD_H + +#define SPD_LEN 256 + +#define SPD_DRAM_TYPE 2 +#define SPD_DRAM_DDR3 0x0b +#define SPD_DRAM_LPDDR3 0xf1 +#define SPD_DENSITY_BANKS 4 +#define SPD_ADDRESSING 5 +#define SPD_ORGANIZATION 7 +#define SPD_BUS_DEV_WIDTH 8 +#define SPD_PART_OFF 128 +#define SPD_PART_LEN 18 +#define SPD_MANU_OFF 148 + +#define HYNIX_SINGLE_CHAN 0x1 +#define SAMSUNG_SINGLE_CHAN 0x4 +#define MIC_SINGLE_CHAN 0x5 + +/* PCH_MEM_CFG[3:0] */ +#define MAX_MEMORY_CONFIG 0x10 +#define RCOMP_TARGET_PARAMS 0x5 +#define K4E6E304EE_MEM_ID 0x3 + +static inline int get_spd_index(void) +{ + /* PCH_MEM_CFG[3:0] */ + gpio_t spd_gpios[] = { + GPIO_MEM_CONFIG_0, + GPIO_MEM_CONFIG_1, + GPIO_MEM_CONFIG_2, + GPIO_MEM_CONFIG_3, + }; + return gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios)); +} +void mainboard_fill_dq_map_data(void *dq_map_ptr); +void mainboard_fill_dqs_map_data(void *dqs_map_ptr); +void mainboard_fill_rcomp_res_data(void *rcomp_ptr); +void mainboard_fill_rcomp_strength_data(void *rcomp_strength_ptr); +uintptr_t mainboard_get_spd_data(void); +int mainboard_has_dual_channel_mem(void); +#endif diff --git a/src/mainboard/intel/kblrvp/spd/spd_util.c b/src/mainboard/intel/kblrvp/spd/spd_util.c new file mode 100644 index 0000000000..fc0581cb24 --- /dev/null +++ b/src/mainboard/intel/kblrvp/spd/spd_util.c @@ -0,0 +1,118 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 Intel Corporation. + * + * 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 +#include +#include +#include +#include +#include +#include +#include "boardid.h" +#include "spd.h" + +void mainboard_fill_dq_map_data(void *dq_map_ptr) +{ + /* DQ byte map */ + const u8 dq_map[2][12] = { + { 0x0F, 0xF0, 0x00, 0xF0, 0x0F, 0xF0, + 0x0F, 0x00, 0xFF, 0x00, 0xFF, 0x00 }, + { 0x0F, 0xF0, 0x00, 0xF0, 0x0F, 0xF0, + 0x0F, 0x00, 0xFF, 0x00, 0xFF, 0x00 } }; + memcpy(dq_map_ptr, dq_map, sizeof(dq_map)); +} + +void mainboard_fill_dqs_map_data(void *dqs_map_ptr) +{ + /* DQS CPU<>DRAM map */ + const u8 dqs_map[2][8] = { + { 0, 1, 3, 2, 6, 5, 4, 7 }, + { 2, 3, 0, 1, 6, 7, 4, 5 } }; + memcpy(dqs_map_ptr, dqs_map, sizeof(dqs_map)); +} + +void mainboard_fill_rcomp_res_data(void *rcomp_ptr) +{ + /* Rcomp resistor */ + const u16 RcompResistor[3] = { 200, 81, 162 }; + memcpy(rcomp_ptr, RcompResistor, + sizeof(RcompResistor)); +} + +void mainboard_fill_rcomp_strength_data(void *rcomp_strength_ptr) +{ + int mem_cfg_id; + + mem_cfg_id = get_spd_index(); + /* Rcomp target */ + static const u16 RcompTarget[RCOMP_TARGET_PARAMS] = { + 100, 40, 40, 23, 40 }; + + /* Strengthen the Rcomp Target Ctrl for 8GB K4E6E304EE -EGCF */ + static const u16 StrengthendRcompTarget[RCOMP_TARGET_PARAMS] = { + 100, 40, 40, 21, 40 }; + + + if (mem_cfg_id == K4E6E304EE_MEM_ID) { + memcpy(rcomp_strength_ptr, StrengthendRcompTarget, + sizeof(StrengthendRcompTarget)); + } else { + memcpy(rcomp_strength_ptr, RcompTarget, sizeof(RcompTarget)); + } + +} + +uintptr_t mainboard_get_spd_data(void) +{ + char *spd_file; + int spd_index, spd_span; + size_t spd_file_len; + + spd_index = get_spd_index(); + printk(BIOS_INFO, "SPD index %d\n", spd_index); + + /* Load SPD data from CBFS */ + spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, + &spd_file_len); + if (!spd_file) + die("SPD data not found."); + + /* make sure we have at least one SPD in the file. */ + if (spd_file_len < SPD_LEN) + die("Missing SPD data."); + + /* Make sure we did not overrun the buffer */ + if (spd_file_len < ((spd_index + 1) * SPD_LEN)) { + printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n"); + spd_index = 0; + } + + spd_span = spd_index * SPD_LEN; + return (uintptr_t)(spd_file + spd_span); +} + +int mainboard_has_dual_channel_mem(void) +{ + int spd_index; + + spd_index = get_spd_index(); + + if (spd_index != HYNIX_SINGLE_CHAN && spd_index != SAMSUNG_SINGLE_CHAN + && spd_index != MIC_SINGLE_CHAN) { + printk(BIOS_INFO, + "Dual channel SPD detected writing second channel\n"); + return 1; + } + return 0; +} -- cgit v1.2.3