Arthur Heymans (arthur(a)aheymans.xyz) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18320
-gerrit
commit 592032919490b2e88d6dca68d127c87cb470f972
Author: Arthur Heymans <arthur(a)aheymans.xyz>
Date: Fri Feb 10 12:08:16 2017 +0100
device/dram/ddr2: Add common function to select common CAS en freq
This function has a CAS mask as input encoded in the same way as SPD
byte 18.
It tries to find the fastest frequency at the lowest possible CAS
latency.
Change-Id: I3ab39d38a243edddfde8f70ebd23f79ff774e90e
Signed-off-by: Arthur Heymans <arthur(a)aheymans.xyz>
---
src/device/dram/ddr2.c | 87 ++++++++++++++++++++++++++++++++++++++++++
src/include/device/dram/ddr2.h | 15 +++++++-
2 files changed, 101 insertions(+), 1 deletion(-)
diff --git a/src/device/dram/ddr2.c b/src/device/dram/ddr2.c
index b712192..21480eb 100644
--- a/src/device/dram/ddr2.c
+++ b/src/device/dram/ddr2.c
@@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2017 Patrick Rudolph <siro(a)das-labor.org>
+ * Copyright (C) 2017 Arthur Heymans <arthur(a)aheymans.xyz>
*
* 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
@@ -110,6 +111,21 @@ static u8 spd_get_msbs(u8 c)
}
/**
+ * \brief Return index of MSB set
+ *
+ * Returns the index fof MSB set.
+ */
+static u8 spd_get_lsbs(u8 c)
+{
+ int i;
+ for (i = 0; i < 7; i++)
+ if (c & (1 << i))
+ return i;
+
+ return 0;
+}
+
+/**
* \brief Decode SPD tck cycle time
*
* Decodes a raw SPD data from a DDR2 DIMM.
@@ -593,3 +609,74 @@ void dram_print_spd_ddr2(const dimm_attr *dimm)
print_us(" tPLL : ", dimm->tPLL);
print_us(" tRR : ", dimm->tRR);
}
+
+int get_common_freq_cas(u8 max_freq, u8 cas_mask, const dimm_attr *dimm,
+ int num_dimms, u8 *selected_freq, u8 *selected_cas)
+{
+ int i, found, high_supp_cas, low_supp_cas;
+ u8 curr_freq, curr_cas;
+
+ const int ddr2_speeds_table[] = {
+ TCK_200MHZ,
+ TCK_266MHZ,
+ TCK_333MHZ,
+ TCK_400MHZ,
+ TCK_533MHZ,
+ TCK_666MHZ,
+ TCK_700MHZ,
+ TCK_800MHZ,
+ };
+
+ for (i = 0; i < num_dimms; i++) {
+ if (dimm[i].dimm_type == SPD_DIMM_TYPE_UNDEFINED)
+ continue;
+ cas_mask &= dimm[i].cas_supported;
+ }
+
+ if (!cas_mask) {
+ printk(BIOS_DEBUG, "No common supported CAS\n");
+ return 1;
+ }
+
+ high_supp_cas = spd_get_msbs(cas_mask);
+ low_supp_cas = spd_get_lsbs(cas_mask);
+
+ /* Loop from fast to slow frequency, from low to high CAS latency */
+ for (curr_freq = max_freq;
+ curr_freq >= 0; curr_freq--) {
+ printram("Trying speed: %d\n", curr_freq);
+ for (curr_cas = low_supp_cas;
+ curr_cas <= high_supp_cas; curr_cas++) {
+ printram(" Trying CAS: %d\n", curr_cas);
+ found = 1;
+ for (i = 0; i < num_dimms; i++) {
+ if (dimm[i].dimm_type ==
+ SPD_DIMM_TYPE_UNDEFINED)
+ continue;
+
+ printram(" Testing DIMM %d:", i);
+ if (dimm[i].cycle_time[curr_cas] == 0) {
+ printram(" CAS not supported");
+ found = 0;
+ break;
+ }
+
+ if (dimm[i].cycle_time[curr_cas] >
+ ddr2_speeds_table[curr_freq]) {
+ printram(" Timing too fast\n");
+ found = 0;
+ break;
+ }
+ printram(" ok\n");
+ }
+ if (found) {
+ *selected_freq = curr_freq;
+ *selected_cas = curr_cas;
+ return 0;
+ }
+ }
+ }
+
+ printk(BIOS_DEBUG, "No common CAS Frequency combination possible!\n");
+ return 1;
+}
diff --git a/src/include/device/dram/ddr2.h b/src/include/device/dram/ddr2.h
index 236be49..8bfcfc1 100644
--- a/src/include/device/dram/ddr2.h
+++ b/src/include/device/dram/ddr2.h
@@ -46,6 +46,18 @@
#define TCK_333MHZ 768
#define TCK_266MHZ 960
#define TCK_200MHZ 1280
+
+enum dram_freq {
+ DDR2_200MHZ,
+ DDR2_266MHZ,
+ DDR2_333MHZ,
+ DDR2_400MHZ,
+ DDR2_533MHZ,
+ DDR2_666MHZ,
+ DDR2_700MHZ,
+ DDR2_800MHZ,
+};
+
/** @} */
/**
@@ -198,6 +210,7 @@ u32 spd_decode_spd_size_ddr2(u8 byte0);
u32 spd_decode_eeprom_size_ddr2(u8 byte1);
int spd_decode_ddr2(dimm_attr *dimm, spd_raw_data spd);
void dram_print_spd_ddr2(const dimm_attr *dimm);
-
+int get_common_freq_cas(u8 max_freq, u8 cas_mask, const dimm_attr *dimm,
+ int num_dimms, u8 *selected_freq, u8 *selected_cas);
#endif /* DEVICE_DRAM_DDR2L_H */
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18322
-gerrit
commit 24de2e44d02a8981ca60f40e3acc383438c14a98
Author: Patrick Georgi <pgeorgi(a)chromium.org>
Date: Fri Feb 10 14:59:27 2017 +0100
google/gru: Fix whitespace
Change-Id: I538c28fb1bc412947ef9df947fa3f6a3312aeb4b
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
---
src/mainboard/google/gru/Kconfig.name | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/mainboard/google/gru/Kconfig.name b/src/mainboard/google/gru/Kconfig.name
index deace91..55d7a65 100644
--- a/src/mainboard/google/gru/Kconfig.name
+++ b/src/mainboard/google/gru/Kconfig.name
@@ -13,4 +13,3 @@ config BOARD_GOOGLE_BOB
config BOARD_GOOGLE_SCARLET
bool "Scarlet"
select BOARD_GOOGLE_GRU_COMMON
-
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18297
-gerrit
commit ba2e6d2740a2e0059d26a94761a37af7c509c1b1
Author: Yuji Sasaki <sasakiy(a)google.com>
Date: Thu Jan 26 10:17:45 2017 -0800
qualcomm/ipq40xx: add vector operation method to SPI
Adding spi_xfer_two_vectors as .xfer_vector for ipq40xx spi_ctrlr.
Commit c2973d196d1 ("UPSTREAM: spi: Get rid of SPI_ATOMIC_SEQUENCING")
has added a new driver method xfer_vector to support combined write-read
operation within a single CS cycle. The method is wrapped in the
spi_xfer_vector() API. When spi_ctrlr structure does not have
xfer_vector method, API calls write and read operations sequentially.
However the QCA40xx SPI driver has "forced" CS activation-inactivation
in xfer method, so individual operation will break CS after write
operation, making combined write-read cycle broken.
Adding xfer_vector method to spi_ctrlr is a simple fix to prevent this.
BUG=None
BRANCH=none
TEST=built and run on Gale
Change-Id: I2258e563d0793bcacd626f78b8e96b3649a8e4a4
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: 88a8824951cef4fe293dfa6e3a1a837ae07b6156
Original-Change-Id: I031e85ce5b847353cb1084f6f68b2af8c6f702e1
Original-Signed-off-by: Yuji Sasaki <sasakiy(a)google.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/433439
Original-Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
Original-Reviewed-by: Kan Yan <kyan(a)google.com>
---
src/soc/qualcomm/ipq40xx/spi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/soc/qualcomm/ipq40xx/spi.c b/src/soc/qualcomm/ipq40xx/spi.c
index 6d044b3..68c2dd0 100644
--- a/src/soc/qualcomm/ipq40xx/spi.c
+++ b/src/soc/qualcomm/ipq40xx/spi.c
@@ -656,6 +656,7 @@ static const struct spi_ctrlr spi_ctrlr = {
.claim_bus = spi_ctrlr_claim_bus,
.release_bus = spi_ctrlr_release_bus,
.xfer = spi_ctrlr_xfer,
+ .xfer_vector = spi_xfer_two_vectors,
};
int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)