Subrata Banik (subrata.banik(a)intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18221
-gerrit
commit 9d73aeb8c591ee614e4151683b53de69b2af7983
Author: Subrata Banik <subrata.banik(a)intel.com>
Date: Tue Jan 24 18:53:10 2017 +0530
soc/intel/common/block: Add Intel XHCI driver support
Create sample model for common Intel XHCI driver.
Change-Id: I81f57bc713900c96d998bae924fc4d38a9024fe3
Signed-off-by: Subrata Banik <subrata.banik(a)intel.com>
---
src/Kconfig | 3 ++
src/soc/intel/common/block/include/xhci.h | 22 ++++++++++++++
src/soc/intel/common/block/xhci/Kconfig | 4 +++
src/soc/intel/common/block/xhci/Makefile.inc | 7 +++++
src/soc/intel/common/block/xhci/xhci.c | 45 ++++++++++++++++++++++++++++
5 files changed, 81 insertions(+)
diff --git a/src/Kconfig b/src/Kconfig
index 436964c..e6e8e03 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -471,6 +471,9 @@ source "src/ec/*/*/Kconfig"
# FIXME move to vendorcode
source "src/drivers/intel/fsp1_0/Kconfig"
+# Intel SoC Family IP model Kconfig
+source "src/soc/intel/common/block/*/Kconfig"
+
source "src/southbridge/intel/common/firmware/Kconfig"
source "src/vboot/Kconfig"
source "src/vendorcode/*/Kconfig"
diff --git a/src/soc/intel/common/block/include/xhci.h b/src/soc/intel/common/block/include/xhci.h
new file mode 100644
index 0000000..1ad1c4e
--- /dev/null
+++ b/src/soc/intel/common/block/include/xhci.h
@@ -0,0 +1,22 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2017 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 __XHCI_H
+#define __XHCI_H
+
+void xhci_init(struct device *dev);
+
+#endif /* __XHCI_H */
+
diff --git a/src/soc/intel/common/block/xhci/Kconfig b/src/soc/intel/common/block/xhci/Kconfig
new file mode 100644
index 0000000..7070dd3
--- /dev/null
+++ b/src/soc/intel/common/block/xhci/Kconfig
@@ -0,0 +1,4 @@
+config SOC_INTEL_XHCI_DRIVER
+ bool
+ help
+ Intel Processor XHCI Driver support
diff --git a/src/soc/intel/common/block/xhci/Makefile.inc b/src/soc/intel/common/block/xhci/Makefile.inc
new file mode 100644
index 0000000..826f3da
--- /dev/null
+++ b/src/soc/intel/common/block/xhci/Makefile.inc
@@ -0,0 +1,7 @@
+ifeq ($(CONFIG_SOC_INTEL_XHCI_DRIVER),y)
+
+ramstage-y += xhci.c
+
+CPPFLAGS_common += -I$(src)/soc/intel/common/block/include
+
+endif
diff --git a/src/soc/intel/common/block/xhci/xhci.c b/src/soc/intel/common/block/xhci/xhci.c
new file mode 100644
index 0000000..790129b
--- /dev/null
+++ b/src/soc/intel/common/block/xhci/xhci.c
@@ -0,0 +1,45 @@
+/*
+ * 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 <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <xhci.h>
+
+__attribute__((weak)) void xhci_init(struct device *dev) { /* no-op */ }
+
+static struct device_operations usb_xhci_ops = {
+ .read_resources = &pci_dev_read_resources,
+ .set_resources = &pci_dev_set_resources,
+ .enable_resources = &pci_dev_enable_resources,
+ .ops_pci = &soc_pci_ops,
+ .init = xhci_init,
+};
+
+static const unsigned short pci_device_ids[] = {
+ 0x5aa8, /* ApolloLake */
+ 0x31a8, /* GLK */
+ 0x9d2f, /* SunRisePoint LP */
+ 0
+};
+
+static const struct pci_driver pch_usb_xhci __pci_driver = {
+ .ops = &usb_xhci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = pci_device_ids,
+};
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 540809ec1c6efb47ea35003f370a8a0af7616f1f
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 CAS and Frequency masks as inputs to support
northbridges that have different limits on those. The CAS mask is
used as defined in SPD and frequency mask is bitwise mask for
supported frequency so e.g. if 200 and 266MHz are supported freq_mask
would be (1 << DDR2_200MHZ) | (1 << DDR2_266MHZ).
Change-Id: I3ab39d38a243edddfde8f70ebd23f79ff774e90e
Signed-off-by: Arthur Heymans <arthur(a)aheymans.xyz>
---
src/device/dram/ddr2.c | 86 ++++++++++++++++++++++++++++++++++++++++++
src/include/device/dram/ddr2.h | 15 +++++++-
2 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/src/device/dram/ddr2.c b/src/device/dram/ddr2.c
index b712192..f520904 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,73 @@ 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 freq_mask, 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 = spd_get_msbs(freq_mask);
+ curr_freq >= spd_get_lsbs(freq_mask); curr_freq--) {
+ printram("Trying speed: %d\n", curr_freq);
+ for (curr_cas = low_supp_cas;
+ curr_cas <= low_supp_cas; curr_cas++) {
+ printram(" Trying CAS: %d\n"; curr_freq);
+ found = 1;
+ for (i = 0; i < num_dimms; i++) {
+ if (dimm[i]->dimm_type ==
+ SPD_DIMM_TYPE_UNDEFINED)
+ continue;
+
+ printram(" Testing DIMM: %d\n", 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;
+ }
+ }
+ 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..24d3379 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 freq_mask, u8 cas_mask, const dimm_attr **dimm,
+ int num_dimms, u8 *selected_freq, u8 *selected_cas);
#endif /* DEVICE_DRAM_DDR2L_H */