diff options
author | Aamir Bohra <aamir.bohra@intel.com> | 2018-07-01 00:31:05 +0530 |
---|---|---|
committer | Subrata Banik <subrata.banik@intel.com> | 2018-11-23 06:16:15 +0000 |
commit | 4041bcf629c9b0239cca7a71091f6e6f0c669b4b (patch) | |
tree | 74d66674c3f1b5207a930b9a90ca96fe944d3b88 | |
parent | 2fd2923aebae63bdf4567f70d933831f44e082ed (diff) |
mb/intel/icelake_rvp: Add ICL U and Y RVP DIMM configuration
List of ICL board variants
1. ICL-U
DDR4 - All possible DDR4 memory type
LPDDR4 - Memory down fixed DIMM configuration
2. ICL-Y
All LPDDR4 DIMM on platform
This patch ensures to have all proper SPD configuration.
Change-Id: Id596a3c85b13559b3002dcadfee9c945256e28e7
Signed-off-by: Subrata Banik <subrata.banik@intel.com>
Signed-off-by: Aamir Bohra <aamir.bohra@intel.com>
Reviewed-on: https://review.coreboot.org/c/29770
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Shelley Chen <shchen@google.com>
-rw-r--r-- | src/mainboard/intel/icelake_rvp/Makefile.inc | 2 | ||||
-rw-r--r-- | src/mainboard/intel/icelake_rvp/board_id.c | 51 | ||||
-rw-r--r-- | src/mainboard/intel/icelake_rvp/board_id.h | 28 | ||||
-rw-r--r-- | src/mainboard/intel/icelake_rvp/spd/Makefile.inc | 16 | ||||
-rw-r--r-- | src/mainboard/intel/icelake_rvp/spd/samsung_K4F6E304HBMGCJ.spd.hex | 32 | ||||
-rw-r--r-- | src/mainboard/intel/icelake_rvp/spd/spd_util.c | 107 |
6 files changed, 212 insertions, 24 deletions
diff --git a/src/mainboard/intel/icelake_rvp/Makefile.inc b/src/mainboard/intel/icelake_rvp/Makefile.inc index ef0fb34f1b..f63b4bf531 100644 --- a/src/mainboard/intel/icelake_rvp/Makefile.inc +++ b/src/mainboard/intel/icelake_rvp/Makefile.inc @@ -22,9 +22,11 @@ verstage-$(CONFIG_CHROMEOS) += chromeos.c romstage-$(CONFIG_CHROMEOS) += chromeos.c romstage-y += romstage_fsp_params.c +romstage-y += board_id.c ramstage-$(CONFIG_CHROMEOS) += chromeos.c ramstage-y += mainboard.c +ramstage-y += board_id.c subdirs-y += variants/baseboard CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/baseboard/include diff --git a/src/mainboard/intel/icelake_rvp/board_id.c b/src/mainboard/intel/icelake_rvp/board_id.c new file mode 100644 index 0000000000..6ac312ad8d --- /dev/null +++ b/src/mainboard/intel/icelake_rvp/board_id.c @@ -0,0 +1,51 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 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 "board_id.h" +#include <boardid.h> +#include <ec/acpi/ec.h> +#include <stdint.h> +#include <ec/google/chromeec/ec.h> + +static int get_board_id_via_ext_ec(void) +{ + uint32_t id = BOARD_ID_INIT; + + if (google_chromeec_get_board_version(&id)) + id = BOARD_ID_UNKNOWN; + + return id; +} + +/* Get Board ID via EC I/O port write/read */ +int get_board_id(void) +{ + MAYBE_STATIC int id = -1; + + if (id < 0) { + if (IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)) + id = get_board_id_via_ext_ec(); + else{ + uint8_t buffer[2]; + uint8_t index; + if (send_ec_command(EC_FAB_ID_CMD) == 0) { + for (index = 0; index < sizeof(buffer); index++) + buffer[index] = recv_ec_data(); + id = (buffer[0] << 8) | buffer[1]; + } + } + } + + return id; +} diff --git a/src/mainboard/intel/icelake_rvp/board_id.h b/src/mainboard/intel/icelake_rvp/board_id.h new file mode 100644 index 0000000000..3ccfe37f42 --- /dev/null +++ b/src/mainboard/intel/icelake_rvp/board_id.h @@ -0,0 +1,28 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 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_BOARD_ID_H_ +#define _MAINBOARD_BOARD_ID_H_ + +/* Board/FAB ID Command */ +#define EC_FAB_ID_CMD 0x0D + +/* + * Returns board information (board id[15:8] and + * Fab info[7:0]) on success and < 0 on error + */ +int get_board_id(void); + +#endif /* _MAINBOARD_BOARD_ID_H_ */ diff --git a/src/mainboard/intel/icelake_rvp/spd/Makefile.inc b/src/mainboard/intel/icelake_rvp/spd/Makefile.inc index 854a491c90..d92ce96308 100644 --- a/src/mainboard/intel/icelake_rvp/spd/Makefile.inc +++ b/src/mainboard/intel/icelake_rvp/spd/Makefile.inc @@ -17,11 +17,11 @@ romstage-y += spd_util.c SPD_BIN = $(obj)/spd.bin -SPD_SOURCES = empty # 0b000 -SPD_SOURCES += empty # 0b001 -SPD_SOURCES += empty # 0b001 -SPD_SOURCES += empty # 0b011 -SPD_SOURCES += empty # 0b100 -SPD_SOURCES += empty # 0b101 -SPD_SOURCES += empty # 0b110 -SPD_SOURCES += empty # 0b111 +SPD_SOURCES = empty # 0b000 +SPD_SOURCES += samsung_K4F6E304HBMGCJ # 1b001 +SPD_SOURCES += empty # 2b010 +SPD_SOURCES += empty # 3b011 +SPD_SOURCES += samsung_K4F6E304HBMGCJ # 4b100 +SPD_SOURCES += empty # 5b101 +SPD_SOURCES += samsung_K4F6E304HBMGCJ # 6b110 +SPD_SOURCES += empty # 7b111 diff --git a/src/mainboard/intel/icelake_rvp/spd/samsung_K4F6E304HBMGCJ.spd.hex b/src/mainboard/intel/icelake_rvp/spd/samsung_K4F6E304HBMGCJ.spd.hex new file mode 100644 index 0000000000..62dff16182 --- /dev/null +++ b/src/mainboard/intel/icelake_rvp/spd/samsung_K4F6E304HBMGCJ.spd.hex @@ -0,0 +1,32 @@ +23 11 10 0E 15 19 94 08 00 40 00 00 0A 22 00 00 +00 00 05 0F 92 54 01 00 8A 00 90 A8 90 A0 05 D0 +02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 92 00 A7 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 20 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 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/icelake_rvp/spd/spd_util.c b/src/mainboard/intel/icelake_rvp/spd/spd_util.c index 25f7f20887..63b39fd3f4 100644 --- a/src/mainboard/intel/icelake_rvp/spd/spd_util.c +++ b/src/mainboard/intel/icelake_rvp/spd/spd_util.c @@ -13,11 +13,21 @@ * GNU General Public License for more details. */ #include <arch/byteorder.h> +#include <arch/cpu.h> #include <console/console.h> +#include <intelblocks/mp_init.h> #include <stdint.h> #include <string.h> +#include "../board_id.h" #include "spd.h" +enum icl_dimm_type { + icl_u_ddr4 = 0, + icl_u_lpddr4 = 1, + icl_u_lpddr4_type_3 = 4, + icl_y_lpddr4 = 6 +}; + void mainboard_fill_dq_map_ch0(void *dq_map_ptr) { /* DQ byte map Ch0 */ @@ -37,30 +47,61 @@ void mainboard_fill_dq_map_ch1(void *dq_map_ptr) memcpy(dq_map_ptr, dq_map, sizeof(dq_map)); } +static uint8_t get_spd_index(void) +{ + uint8_t spd_index = (get_board_id() & 0x1F) & 0x7; + + return spd_index; +} + void mainboard_fill_dqs_map_ch0(void *dqs_map_ptr) { /* DQS CPU<>DRAM map Ch0 */ - const u8 dqs_map_u[8] = { 0, 3, 2, 1, 5, 6, 7, 4 }; - - const u8 dqs_map_y[8] = { 2, 0, 3, 1, 6, 5, 7, 4 }; + const u8 dqs_map_u_ddr[8] = { 2, 0, 1, 3, 6, 4, 7, 5 }; + const u8 dqs_map_u_lpddr[8] = { 2, 3, 0, 1, 7, 6, 4, 5 }; + const u8 dqs_map_u_lpddr_type_3[8] = { 2, 3, 1, 0, 7, 6, 4, 5 }; + const u8 dqs_map_y_lpddr[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - if (IS_ENABLED(CONFIG_BOARD_INTEL_ICELAKE_RVPU)) - memcpy(dqs_map_ptr, dqs_map_u, sizeof(dqs_map_u)); - else - memcpy(dqs_map_ptr, dqs_map_y, sizeof(dqs_map_y)); + switch (get_spd_index()) { + case icl_u_ddr4: + memcpy(dqs_map_ptr, dqs_map_u_ddr, sizeof(dqs_map_u_ddr)); + break; + case icl_u_lpddr4: + memcpy(dqs_map_ptr, dqs_map_u_lpddr, sizeof(dqs_map_u_lpddr)); + break; + case icl_u_lpddr4_type_3: + memcpy(dqs_map_ptr, dqs_map_u_lpddr_type_3, + sizeof(dqs_map_u_lpddr_type_3)); + break; + case icl_y_lpddr4: + memcpy(dqs_map_ptr, dqs_map_y_lpddr, sizeof(dqs_map_y_lpddr)); + break; + default: + break; + } } void mainboard_fill_dqs_map_ch1(void *dqs_map_ptr) { /* DQS CPU<>DRAM map Ch1 */ - const u8 dqs_map_u[8] = { 3, 0, 1, 2, 5, 6, 4, 7 }; - - const u8 dqs_map_y[8] = { 3, 1, 2, 0, 4, 5, 6, 7 }; + const u8 dqs_map_u_ddr[8] = { 1, 3, 2, 0, 5, 7, 6, 4 }; + const u8 dqs_map_u_lpddr[8] = { 1, 0, 3, 2, 5, 4, 7, 6 }; + const u8 dqs_map_y_lpddr[8] = { 0, 1, 2, 3, 5, 4, 7, 6 }; - if (IS_ENABLED(CONFIG_BOARD_INTEL_ICELAKE_RVPU)) - memcpy(dqs_map_ptr, dqs_map_u, sizeof(dqs_map_u)); - else - memcpy(dqs_map_ptr, dqs_map_y, sizeof(dqs_map_y)); + switch (get_spd_index()) { + case icl_u_ddr4: + memcpy(dqs_map_ptr, dqs_map_u_ddr, sizeof(dqs_map_u_ddr)); + break; + case icl_u_lpddr4: + case icl_u_lpddr4_type_3: + memcpy(dqs_map_ptr, dqs_map_u_lpddr, sizeof(dqs_map_u_lpddr)); + break; + case icl_y_lpddr4: + memcpy(dqs_map_ptr, dqs_map_y_lpddr, sizeof(dqs_map_y_lpddr)); + break; + default: + break; + } } void mainboard_fill_rcomp_res_data(void *rcomp_ptr) @@ -70,11 +111,45 @@ void mainboard_fill_rcomp_res_data(void *rcomp_ptr) memcpy(rcomp_ptr, RcompResistor, sizeof(RcompResistor)); } +/* + * get processor id using cpuid eax=1 + * return value will be in EAX register + */ +static uint32_t get_cpuid(void) +{ + struct cpuid_result cpuidr; + + cpuidr = cpuid(1); + + return cpuidr.eax; +} + void mainboard_fill_rcomp_strength_data(void *rcomp_strength_ptr) { /* Rcomp target */ - static const u16 RcompTarget[RCOMP_TARGET_PARAMS] = { + static const u16 RcompTarget_DDR4[RCOMP_TARGET_PARAMS] = { + 100, 33, 32, 33, 28 }; + static const u16 RcompTarget_LPDDR4_Ax[RCOMP_TARGET_PARAMS] = { 80, 40, 40, 40, 30 }; + static const u16 RcompTarget_LPDDR4_Bx[RCOMP_TARGET_PARAMS] = { + 60, 20, 20, 20, 20 }; - memcpy(rcomp_strength_ptr, RcompTarget, sizeof(RcompTarget)); + switch (get_spd_index()) { + case icl_u_ddr4: + memcpy(rcomp_strength_ptr, RcompTarget_DDR4, + sizeof(RcompTarget_DDR4)); + break; + case icl_y_lpddr4: + case icl_u_lpddr4: + case icl_u_lpddr4_type_3: + if (get_cpuid() == CPUID_ICELAKE_A0) + memcpy(rcomp_strength_ptr, RcompTarget_LPDDR4_Ax, + sizeof(RcompTarget_LPDDR4_Ax)); + else + memcpy(rcomp_strength_ptr, RcompTarget_LPDDR4_Bx, + sizeof(RcompTarget_LPDDR4_Bx)); + break; + default: + break; + } } |