Werner Zeh (werner.zeh(a)siemens.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8404
-gerrit
commit a183e2cd3dc4913aec840111fdc269aaf7ee7a4f
Author: Werner Zeh <werner.zeh(a)siemens.com>
Date: Tue Feb 10 15:09:00 2015 +0100
drivers/intel/i210: Add new driver for Intel i210 MACPHY
Add a new driver for Intel i210 MACPHY with the goal to
update the MAC address in i210 if it is found
during PCI scan.
Change-Id: I4d4e797543a9f278fb649596f63ae8e1f285b3c3
Signed-off-by: Werner Zeh <werner.zeh(a)siemens.com>
---
src/drivers/intel/Kconfig | 1 +
src/drivers/intel/Makefile.inc | 1 +
src/drivers/intel/i210/Kconfig | 3 +
src/drivers/intel/i210/Makefile.inc | 1 +
src/drivers/intel/i210/i210.c | 241 ++++++++++++++++++++++++++++++++++++
src/drivers/intel/i210/i210.h | 56 +++++++++
6 files changed, 303 insertions(+)
diff --git a/src/drivers/intel/Kconfig b/src/drivers/intel/Kconfig
index 9954f31..511cf5c 100644
--- a/src/drivers/intel/Kconfig
+++ b/src/drivers/intel/Kconfig
@@ -18,3 +18,4 @@
##
source src/drivers/intel/gma/Kconfig
+source src/drivers/intel/i210/Kconfig
diff --git a/src/drivers/intel/Makefile.inc b/src/drivers/intel/Makefile.inc
index 7bc6dd5..6cf8f00 100644
--- a/src/drivers/intel/Makefile.inc
+++ b/src/drivers/intel/Makefile.inc
@@ -1,3 +1,4 @@
subdirs-y += gma
subdirs-y += wifi
subdirs-$(CONFIG_PLATFORM_USES_FSP) += fsp
+subdirs-$(CONFIG_DRIVER_INTEL_I210) += i210
\ No newline at end of file
diff --git a/src/drivers/intel/i210/Kconfig b/src/drivers/intel/i210/Kconfig
new file mode 100644
index 0000000..77d30e9
--- /dev/null
+++ b/src/drivers/intel/i210/Kconfig
@@ -0,0 +1,3 @@
+config CONFIG_DRIVER_INTEL_I210
+ bool
+ default n
\ No newline at end of file
diff --git a/src/drivers/intel/i210/Makefile.inc b/src/drivers/intel/i210/Makefile.inc
new file mode 100644
index 0000000..a1f15de
--- /dev/null
+++ b/src/drivers/intel/i210/Makefile.inc
@@ -0,0 +1 @@
+ramstage-y += i210.c
\ No newline at end of file
diff --git a/src/drivers/intel/i210/i210.c b/src/drivers/intel/i210/i210.c
new file mode 100644
index 0000000..76326a8
--- /dev/null
+++ b/src/drivers/intel/i210/i210.c
@@ -0,0 +1,241 @@
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "i210.h"
+#include <device/device.h>
+#include <console/console.h>
+#include <string.h>
+#include <types.h>
+
+/* We need one function we can call to get a MAC address to use */
+/* This function can be coded somewhere else but must exist. */
+extern enum cb_err get_mac_address(u32 pci_bdf, u8 mac[6]);
+
+/* This is a private function to wait for a bit mask in a given register */
+/* To avoid endless loops, a time-out is implemented here. */
+static int wait_done(u32* reg, u32 mask)
+{
+ u32 timeout = I210_POLL_TIMEOUT_US;
+ do {
+ if (!(*reg & mask)) {
+ udelay(1);
+ timeout--;
+ }
+ } while((!(*reg & mask)) && timeout);
+ return timeout ? I210_NO_ERROR : I210_NOT_READY;
+}
+
+/** \brief This function is the driver entry point for the init phase
+ * of the PCI bus allocator. It will program a MAC address
+ * into the MACPHY.
+ * @param *dev Pointer to the used PCI device
+ * @return void Nothing is given back
+ */
+static void init(struct device *dev)
+{
+ u8 cur_adr[6];
+ u8 adr_to_set[6];
+ enum cb_err status;
+
+ /*Check first whether there is a valid MAC address available */
+ status = get_mac_address((dev->bus->subordinate << 16) |
+ dev->path.pci.devfn << 8, adr_to_set);
+ if (status != CB_SUCCESS) {
+ printk(BIOS_ERR, "I210: No valid MAC address found\n");
+ return;
+ }
+ /* Before we will write a new address, check the existing one */
+ if (read_mac_adr(dev, cur_adr)) {
+ printk(BIOS_ERR, "I210: Not able to read MAC address.\n");
+ return;
+ }
+ if (memcmp(cur_adr, adr_to_set, 6)) {
+ if (write_mac_adr(dev, adr_to_set)) {
+ printk(BIOS_ERR, "I210: Error setting MAC address\n");
+ } else {
+ printk(BIOS_INFO, "I210: MAC address changed.\n");
+ }
+ } else {
+ printk(BIOS_INFO, "I210: MAC address is up to date.\n");
+ }
+ return;
+}
+
+/** \brief This function can read the MAC address out of the MACPHY
+ * @param *dev Pointer to the PCI device of this MACPHY
+ * @param *MACAdr Pointer to the buffer where to store read MAC address
+ * @return void I210_NO_ERROR or an error code
+ */
+static u32 read_mac_adr(struct device *dev, u8 *MACAdr)
+{
+ u16 adr[3];
+ if (!dev || !MACAdr)
+ return I210_INVALID_PARAM;
+ if (read_flash(dev, 0, 3, adr))
+ return I210_READ_ERROR;
+ /* Copy the address into destination. This is done because of */
+ /* possible not matching alignment for destination to u16 boundary. */
+ memcpy(MACAdr, (u8*)adr, 6);
+ return I210_NO_ERROR;
+}
+
+/** \brief This function can write the MAC address to the MACPHY
+ * @param *dev Pointer to the PCI device of this MACPHY
+ * @param *MACAdr Pointer to the buffer where the desired MAC address is
+ * @return void I210_NO_ERROR or an error code
+ */
+static u32 write_mac_adr(struct device *dev, u8 *MACAdr)
+{
+ u16 adr[3];
+ if (!dev || !MACAdr)
+ return I210_INVALID_PARAM;
+ /* Copy desired address into a local buffer to avoid alignment issues */
+ memcpy((u8*)adr, MACAdr, 6);
+ return write_flash(dev, 0, 3, adr);
+}
+
+/** \brief This function can read the configuration space of the MACPHY
+ * For this purpose, the EEPROM interface is used. No direct access
+ * to the flash memory will be done.
+ * @param *dev Pointer to the PCI device of this MACPHY
+ * @param address Address inside the flash where reading will start
+ * @param count Number of words (16 bit values) to read
+ * @param *buffer Pointer to the buffer where to store read data
+ * @return void I210_NO_ERROR or an error code
+ */
+static u32 read_flash(struct device *dev, u32 address, u32 count, u16 *buffer)
+{
+ u32 bar;
+ u32 *eeprd;
+ u32 i;
+
+ /* Get the BAR to memory mapped space*/
+ bar = pci_read_config32(dev, 0x10);
+ if ((!bar) || ((address + count) > 0x40))
+ return I210_INVALID_PARAM;
+ eeprd = (u32*)(bar + I210_REG_EEREAD);
+ /* Prior to start ensure flash interface is ready by checking DONE-bit */
+ if (wait_done(eeprd, I210_DONE))
+ return I210_NOT_READY;
+
+ /*OK, interface is ready, we can use it now */
+ for (i = 0; i < count; i++) {
+ /* To start a read cycle write desired address in bits 12..2 */
+ *eeprd = ((address + i) << 2) & 0x1FFC;
+ /* Wait until read is done */
+ if (wait_done(eeprd, I210_DONE))
+ return I210_READ_ERROR;
+ /* Here, we can read back desired word in bits 31..16 */
+ buffer[i] = (*eeprd & 0xffff0000) >> 16;
+ }
+ return I210_NO_ERROR;
+}
+
+/** \brief This function can write the configuration space of the MACPHY
+ * For this purpose, the EEPROM interface is used. No direct access
+ * to the flash memory will be done. This function will update
+ * the checksum after a value was changed.
+ * @param *dev Pointer to the PCI device of this MACPHY
+ * @param address Address inside the flash where writing will start
+ * @param count Number of words (16 bit values) to write
+ * @param *buffer Pointer to the buffer where data to write is stored in
+ * @return void I210_NO_ERROR or an error code
+ */
+static u32 write_flash(struct device *dev, u32 address, u32 count, u16 *buffer)
+{
+ u32 bar;
+ u32 *eepwr;
+ u32 *eectrl;
+ u16 checksum;
+ u32 i;
+
+ /* Get the BAR to memory mapped space */
+ bar = pci_read_config32(dev, 0x10);
+ if ((!bar) || ((address + count) > 0x40))
+ return I210_INVALID_PARAM;
+ eepwr = (u32*)(bar + I210_REG_EEWRITE);
+ eectrl = (u32*)(bar + I210_REG_EECTRL);
+ /* Prior to start ensure flash interface is ready by checking DONE-bit */
+ if (wait_done(eepwr, I210_DONE))
+ return I210_NOT_READY;
+
+ /* OK, interface is ready, we can use it now */
+ for (i = 0; i < count; i++) {
+ /* To start a write cycle write desired address in bits 12..2 */
+ /* and data to write in bits 31..16 into EEWRITE-register */
+ *eepwr = ((((address + i) << 2) & 0x1FFC) | (buffer[i] << 16));
+ /* Wait until write is done */
+ if (wait_done(eepwr, I210_DONE))
+ return I210_WRITE_ERROR;
+ }
+ /* Since we have modified data, we need to update the checksum */
+ if (compute_checksum(dev, &checksum))
+ return I210_CHECKSUM_ERROR;
+ *eepwr = (0x3f << 2) | checksum << 16;
+ if (wait_done(eepwr, I210_DONE))
+ return I210_WRITE_ERROR;
+ /* Up to now, desired data was written into shadowed RAM. We now need */
+ /* to perform a flash cycle to bring the shadowed RAM into flash memory. */
+ /* To start a flash cycle we need to set FLUPD-bit and wait for FLDONE. */
+ *eectrl = *eectrl | I210_FLUPD;
+ if (wait_done(eectrl, I210_FLUDONE))
+ return I210_FLASH_UPDATE_ERROR;
+ else
+ return I210_NO_ERROR;
+}
+
+/** \brief This function computes the checksum for the configuration space.
+ * The address range for the checksum is 0x00..0x3e.
+ * @param *dev Pointer to the PCI device of this MACPHY
+ * @param *checksum Pointer to the buffer where to store the checksum
+ * @return void I210_NO_ERROR or an error code
+ */
+static u32 compute_checksum(struct device *dev, u16 *checksum)
+{
+ u16 eep_data[0x40];
+ u32 i;
+
+ /* First read back data to compute the checksum for */
+ if (read_flash(dev, 0, 0x3f, eep_data))
+ return I210_READ_ERROR;
+ /* The checksum is computed in that way that after summarize all the */
+ /* data from word address 0 to 0x3f the result is 0xBABA. */
+ *checksum = 0;
+ for (i = 0; i < 0x3f; i++)
+ *checksum += eep_data[i];
+ *checksum = I210_TARGET_CHECKSUM - *checksum;
+ return I210_NO_ERROR;
+}
+
+static struct device_operations i210_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = init,
+ .scan_bus = 0,
+ .ops_pci = 0,
+};
+
+static const unsigned short i210_device_ids[] = { 0x1538, 0x1533, 0 };
+
+static const struct pci_driver i210_driver __pci_driver = {
+ .ops = &i210_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = i210_device_ids,
+};
diff --git a/src/drivers/intel/i210/i210.h b/src/drivers/intel/i210/i210.h
new file mode 100644
index 0000000..c1fd58a
--- /dev/null
+++ b/src/drivers/intel/i210/i210.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _INTEL_I210_H_
+#define _INTEL_I210_H_
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <delay.h>
+
+#define I210_PCI_MEM_BAR_OFFSET 0x10
+#define I210_REG_EECTRL 0x12010 /* Offset for EEPROM control reg */
+#define I210_FLUPD 0x800000 /* Start flash update bit */
+#define I210_FLUDONE 0x4000000 /* Flash update done indicator */
+#define I210_REG_EEREAD 0x12014 /* Offset for EEPROM read reg */
+#define I210_REG_EEWRITE 0x12018 /* Offset for EEPROM write reg */
+#define I210_CMDV 0x01 /* command valid bit */
+#define I210_DONE 0x02 /* command done bit */
+#define I210_TARGET_CHECKSUM 0xBABA /* resulting checksum */
+
+
+/*define some other useful values here */
+#define I210_POLL_TIMEOUT_US 300000 /* 300 ms */
+/*Define some error states here*/
+#define I210_NO_ERROR 0x00000000
+#define I210_INVALID_PARAM 0x00000001
+#define I210_NOT_READY 0x00000002
+#define I210_READ_ERROR 0x00000004
+#define I210_WRITE_ERROR 0x00000008
+#define I210_CHECKSUM_ERROR 0x00000010
+#define I210_FLASH_UPDATE_ERROR 0x00000020
+
+static void init(struct device *dev);
+static u32 read_mac_adr(struct device *dev, u8 *MACAdr);
+static u32 write_mac_adr(struct device *dev, u8 *MACAdr);
+static u32 read_flash(struct device *dev, u32 address, u32 count, u16 *buffer);
+static u32 write_flash(struct device *dev, u32 address, u32 count, u16 *buffer);
+static u32 compute_checksum(struct device *dev, u16 *checksum);
+
+#endif /* _INTEL_I210_H_ */
Werner Zeh (werner.zeh(a)siemens.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8399
-gerrit
commit 0ebef485fa75f063cd9f3404e11465baf95d8be4
Author: Werner Zeh <werner.zeh(a)siemens.com>
Date: Tue Feb 10 10:16:12 2015 +0100
Baytrail_fsp: Add new microcode for Baytrail M
Add a new microcode for Baytrail M D0 stepping used
in cpu N2807 silicon.
In addition, a selection of the used CPU type has
beed added (I or M/D) which allows to use only the
realy needed microcode for a given CPU type.
Change-Id: I373fc9b535f1dc97eaa9f76ae46f0b69b247a8a0
Signed-off-by: Werner Zeh <werner.zeh(a)siemens.com>
---
src/soc/intel/fsp_baytrail/Kconfig | 9 +++++++++
src/soc/intel/fsp_baytrail/microcode/microcode_blob.c | 11 ++++++++---
src/soc/intel/fsp_baytrail/microcode/microcode_size.h | 6 +++++-
3 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/src/soc/intel/fsp_baytrail/Kconfig b/src/soc/intel/fsp_baytrail/Kconfig
index 639071a..a7f3f77 100644
--- a/src/soc/intel/fsp_baytrail/Kconfig
+++ b/src/soc/intel/fsp_baytrail/Kconfig
@@ -51,6 +51,15 @@ config CPU_SPECIFIC_OPTIONS
select CPU_MICROCODE_ADDED_DURING_BUILD if INCLUDE_MICROCODE_IN_BUILD
select ROMSTAGE_RTC_INIT
+choice
+ prompt "Baytrail CPU type"
+ default SOC_INTEL_FSP_BAYTRAIL_I
+config SOC_INTEL_FSP_BAYTRAIL_I
+ bool "I"
+config SOC_INTEL_FSP_BAYTRAIL_MD
+ bool "M/D"
+endchoice
+
config BOOTBLOCK_CPU_INIT
string
default "soc/intel/fsp_baytrail/bootblock/bootblock.c"
diff --git a/src/soc/intel/fsp_baytrail/microcode/microcode_blob.c b/src/soc/intel/fsp_baytrail/microcode/microcode_blob.c
index 709ff92..fc5ab08 100644
--- a/src/soc/intel/fsp_baytrail/microcode/microcode_blob.c
+++ b/src/soc/intel/fsp_baytrail/microcode/microcode_blob.c
@@ -19,10 +19,15 @@
unsigned microcode[] = {
+#if IS_ENABLED(CONFIG_SOC_INTEL_FSP_BAYTRAIL_I)
/* Region size is 0x30000 - update in microcode_size.h if it gets larger. */
-#include "M0230672228.h" // M0230672: Baytrail "Super SKU" B0/B1
-#include "M0130673322.h" // M0130673: Baytrail I B2 / B3
-#include "M0130679901.h" // M0130679: Baytrail I D0
+ #include "M0230672228.h" // M0230672: Baytrail "Super SKU" B0/B1
+ #include "M0130673322.h" // M0130673: Baytrail I B2 / B3
+ #include "M0130679901.h" // M0130679: Baytrail I D0
+#elif IS_ENABLED(CONFIG_SOC_INTEL_FSP_BAYTRAIL_MD)
+ /* Region size is 0x10000 - update in microcode_size.h if it gets larger. */
+ #include "M0C30678829.h" // M0C30678: Baytrail M D Stepping
+#endif
/* Dummy terminator */
0x0, 0x0, 0x0, 0x0,
diff --git a/src/soc/intel/fsp_baytrail/microcode/microcode_size.h b/src/soc/intel/fsp_baytrail/microcode/microcode_size.h
index ec55314..213fc17 100644
--- a/src/soc/intel/fsp_baytrail/microcode/microcode_size.h
+++ b/src/soc/intel/fsp_baytrail/microcode/microcode_size.h
@@ -1,2 +1,6 @@
/* Maximum size of the area that the FSP will search for the correct microcode */
-#define MICROCODE_REGION_LENGTH 0x30000
+#if IS_ENABLED(CONFIG_SOC_INTEL_FSP_BAYTRAIL_I)
+ #define MICROCODE_REGION_LENGTH 0x30000
+#elif IS_ENABLED(CONFIG_SOC_INTEL_FSP_BAYTRAIL_MD)
+ #define MICROCODE_REGION_LENGTH 0x10000
+#endif
Timothy Pearson (tpearson(a)raptorengineeringinc.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8405
-gerrit
commit 3691702688a18a037bad5fbe715d78a2468d699e
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Thu Feb 12 01:27:06 2015 -0600
northbridge/amd/amdfam10: Allow mainboards to set maximum HT link frequency
Most K10 mainboards are designed to a maximum HT frequency specification.
Coreboot supports CPUs that were released after mainboard production;
these CPUs may support and autodetect HT link frequencies beyond the
mainboard design capabilities. This patch allows mainboards to set
an HT frequency limit if needed.
Change-Id: If7ff40dccb4c22829062511ca0046aa2caf15580
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
---
src/northbridge/amd/amdfam10/Kconfig | 83 +++++++++++++++++++++++++++++++++---
1 file changed, 78 insertions(+), 5 deletions(-)
diff --git a/src/northbridge/amd/amdfam10/Kconfig b/src/northbridge/amd/amdfam10/Kconfig
index 1c78590..35a683e 100644
--- a/src/northbridge/amd/amdfam10/Kconfig
+++ b/src/northbridge/amd/amdfam10/Kconfig
@@ -124,13 +124,88 @@ config SVI_HIGH_FREQ
Select this for boards with a Voltage Regulator able to operate
at 3.4 MHz in SVI mode. Ignored unless the AMD CPU is rev C3.
+config FORCE_LIMIT_HT_SPEED_200
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_300
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_400
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_500
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_600
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_800
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_1000
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_1200
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_1400
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_1600
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_1800
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_2000
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_2200
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_2400
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_2600
+ bool
+ default n
+
menu "HyperTransport setup"
- #could be implemented for K8 (NORTHBRIDGE_AMD_AMDK8)
- depends on (NORTHBRIDGE_AMD_AMDFAM10) && EXPERT
+ # FIXME uncomment when coreboot gains "visible if" support
+ # visible if EXPERT
choice
prompt "HyperTransport frequency"
- default LIMIT_HT_SPEED_AUTO
+ default LIMIT_HT_SPEED_AUTO if (!FORCE_LIMIT_HT_SPEED_200 && !FORCE_LIMIT_HT_SPEED_300 && !FORCE_LIMIT_HT_SPEED_400 && !FORCE_LIMIT_HT_SPEED_500 && !FORCE_LIMIT_HT_SPEED_600 && !FORCE_LIMIT_HT_SPEED_800 && !FORCE_LIMIT_HT_SPEED_1000 && !FORCE_LIMIT_HT_SPEED_1200 && !FORCE_LIMIT_HT_SPEED_1400 && !FORCE_LIMIT_HT_SPEED_1600 && !FORCE_LIMIT_HT_SPEED_1800 && !FORCE_LIMIT_HT_SPEED_2000 && !FORCE_LIMIT_HT_SPEED_2200 && !FORCE_LIMIT_HT_SPEED_2400 && !FORCE_LIMIT_HT_SPEED_2600)
+ default LIMIT_HT_SPEED_200 if FORCE_LIMIT_HT_SPEED_200
+ default LIMIT_HT_SPEED_300 if FORCE_LIMIT_HT_SPEED_300
+ default LIMIT_HT_SPEED_400 if FORCE_LIMIT_HT_SPEED_400
+ default LIMIT_HT_SPEED_500 if FORCE_LIMIT_HT_SPEED_500
+ default LIMIT_HT_SPEED_600 if FORCE_LIMIT_HT_SPEED_600
+ default LIMIT_HT_SPEED_800 if FORCE_LIMIT_HT_SPEED_800
+ default LIMIT_HT_SPEED_1000 if FORCE_LIMIT_HT_SPEED_1000
+ default LIMIT_HT_SPEED_1200 if FORCE_LIMIT_HT_SPEED_1200
+ default LIMIT_HT_SPEED_1400 if FORCE_LIMIT_HT_SPEED_1400
+ default LIMIT_HT_SPEED_1600 if FORCE_LIMIT_HT_SPEED_1600
+ default LIMIT_HT_SPEED_1800 if FORCE_LIMIT_HT_SPEED_1800
+ default LIMIT_HT_SPEED_2000 if FORCE_LIMIT_HT_SPEED_2000
+ default LIMIT_HT_SPEED_2200 if FORCE_LIMIT_HT_SPEED_2200
+ default LIMIT_HT_SPEED_2400 if FORCE_LIMIT_HT_SPEED_2400
+ default LIMIT_HT_SPEED_2600 if FORCE_LIMIT_HT_SPEED_2600
help
This option sets the maximum permissible HyperTransport link
frequency.
@@ -218,12 +293,10 @@ endchoice
config AMDMCT_ENABLE_ECC_REDIR
bool
- depends on CPU_AMD_MODEL_10XXX
default n
config AMDMCT_BACKGROUND_SCRUB_RATE
hex
- depends on CPU_AMD_MODEL_10XXX
default 0x00
help
This option sets the background ECC memory scub rate
Timothy Pearson (tpearson(a)raptorengineeringinc.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8425
-gerrit
commit 361a65ea2a7a8d71639b82621793c70cbab289d8
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Thu Feb 12 01:25:34 2015 -0600
northbridge/amd/amdfam10: Move K10 specific menu to proper Kconfig file
Change-Id: Ib83ec5c397fdef5aa9e3376f1c0072cfa2f74fa6
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
---
src/northbridge/amd/Kconfig | 134 +----------------------------------
src/northbridge/amd/amdfam10/Kconfig | 132 ++++++++++++++++++++++++++++++++++
2 files changed, 133 insertions(+), 133 deletions(-)
diff --git a/src/northbridge/amd/Kconfig b/src/northbridge/amd/Kconfig
index 17f15c3..4bc6e49 100644
--- a/src/northbridge/amd/Kconfig
+++ b/src/northbridge/amd/Kconfig
@@ -4,136 +4,4 @@ source src/northbridge/amd/amdfam10/Kconfig
source src/northbridge/amd/lx/Kconfig
source src/northbridge/amd/agesa/Kconfig
source src/northbridge/amd/cimx/Kconfig
-source src/northbridge/amd/pi/Kconfig
-
-menu "HyperTransport setup"
- #could be implemented for K8 (NORTHBRIDGE_AMD_AMDK8)
- depends on (NORTHBRIDGE_AMD_AMDFAM10) && EXPERT
-
-choice
- prompt "HyperTransport frequency"
- default LIMIT_HT_SPEED_AUTO
- help
- This option sets the maximum permissible HyperTransport link
- frequency.
-
- Use of this option will only limit the autodetected HT frequency.
- It will not (and cannot) increase the frequency beyond the
- autodetected limits.
-
- This is primarily used to work around poorly designed or laid out
- HT traces on certain motherboards.
-
-config LIMIT_HT_SPEED_200
- bool "Limit HT frequency to 200MHz"
-config LIMIT_HT_SPEED_300
- bool "Limit HT frequency to 300MHz"
-config LIMIT_HT_SPEED_400
- bool "Limit HT frequency to 400MHz"
-config LIMIT_HT_SPEED_500
- bool "Limit HT frequency to 500MHz"
-config LIMIT_HT_SPEED_600
- bool "Limit HT frequency to 600MHz"
-config LIMIT_HT_SPEED_800
- bool "Limit HT frequency to 800MHz"
-config LIMIT_HT_SPEED_1000
- bool "Limit HT frequency to 1.0GHz"
-config LIMIT_HT_SPEED_1200
- bool "Limit HT frequency to 1.2GHz"
-config LIMIT_HT_SPEED_1400
- bool "Limit HT frequency to 1.4GHz"
-config LIMIT_HT_SPEED_1600
- bool "Limit HT frequency to 1.6GHz"
-config LIMIT_HT_SPEED_1800
- bool "Limit HT frequency to 1.8GHz"
-config LIMIT_HT_SPEED_2000
- bool "Limit HT frequency to 2.0GHz"
-config LIMIT_HT_SPEED_2200
- bool "Limit HT frequency to 2.2GHz"
-config LIMIT_HT_SPEED_2400
- bool "Limit HT frequency to 2.4GHz"
-config LIMIT_HT_SPEED_2600
- bool "Limit HT frequency to 2.6GHz"
-config LIMIT_HT_SPEED_AUTO
- bool "Autodetect HT frequency"
-endchoice
-
-choice
- prompt "HyperTransport downlink width"
- default LIMIT_HT_DOWN_WIDTH_16
- help
- This option sets the maximum permissible HyperTransport
- downlink width.
-
- Use of this option will only limit the autodetected HT width.
- It will not (and cannot) increase the width beyond the autodetected
- limits.
-
- This is primarily used to work around poorly designed or laid out HT
- traces on certain motherboards.
-
-config LIMIT_HT_DOWN_WIDTH_8
- bool "8 bits"
-config LIMIT_HT_DOWN_WIDTH_16
- bool "16 bits"
-endchoice
-
-choice
- prompt "HyperTransport uplink width"
- default LIMIT_HT_UP_WIDTH_16
- help
- This option sets the maximum permissible HyperTransport
- uplink width.
-
- Use of this option will only limit the autodetected HT width.
- It will not (and cannot) increase the width beyond the autodetected
- limits.
-
- This is primarily used to work around poorly designed or laid out HT
- traces on certain motherboards.
-
-config LIMIT_HT_UP_WIDTH_8
- bool "8 bits"
-config LIMIT_HT_UP_WIDTH_16
- bool "16 bits"
-endchoice
-
-config AMDMCT_ENABLE_ECC_REDIR
- bool
- depends on CPU_AMD_MODEL_10XXX
- default n
-
-config AMDMCT_BACKGROUND_SCRUB_RATE
- hex
- depends on CPU_AMD_MODEL_10XXX
- default 0x00
- help
- This option sets the background ECC memory scub rate
-
- Permissible values are:
-
- 0x00; Disabled
- 0x01; 40ns
- 0x02; 80ns
- 0x03; 160ns
- 0x04; 320ns
- 0x05; 640ns
- 0x06; 1.28us
- 0x07; 2.56us
- 0x08; 5.12us
- 0x09; 10.2us
- 0x0a; 20.5us
- 0x0b; 41us
- 0x0c; 81.9us
- 0x0d; 163.8us
- 0x0e; 327.7us
- 0x0f; 655.4us
- 0x10; 1.31ms
- 0x11; 2.62ms
- 0x12; 5.24ms
- 0x13; 10.49ms
- 0x14; 20.97sms
- 0x15; 42ms
- 0x16; 84ms
-
-endmenu
+source src/northbridge/amd/pi/Kconfig
\ No newline at end of file
diff --git a/src/northbridge/amd/amdfam10/Kconfig b/src/northbridge/amd/amdfam10/Kconfig
index 13b912e..1c78590 100644
--- a/src/northbridge/amd/amdfam10/Kconfig
+++ b/src/northbridge/amd/amdfam10/Kconfig
@@ -124,4 +124,136 @@ config SVI_HIGH_FREQ
Select this for boards with a Voltage Regulator able to operate
at 3.4 MHz in SVI mode. Ignored unless the AMD CPU is rev C3.
+menu "HyperTransport setup"
+ #could be implemented for K8 (NORTHBRIDGE_AMD_AMDK8)
+ depends on (NORTHBRIDGE_AMD_AMDFAM10) && EXPERT
+
+choice
+ prompt "HyperTransport frequency"
+ default LIMIT_HT_SPEED_AUTO
+ help
+ This option sets the maximum permissible HyperTransport link
+ frequency.
+
+ Use of this option will only limit the autodetected HT frequency.
+ It will not (and cannot) increase the frequency beyond the
+ autodetected limits.
+
+ This is primarily used to work around poorly designed or laid out
+ HT traces on certain motherboards.
+
+config LIMIT_HT_SPEED_200
+ bool "Limit HT frequency to 200MHz"
+config LIMIT_HT_SPEED_300
+ bool "Limit HT frequency to 300MHz"
+config LIMIT_HT_SPEED_400
+ bool "Limit HT frequency to 400MHz"
+config LIMIT_HT_SPEED_500
+ bool "Limit HT frequency to 500MHz"
+config LIMIT_HT_SPEED_600
+ bool "Limit HT frequency to 600MHz"
+config LIMIT_HT_SPEED_800
+ bool "Limit HT frequency to 800MHz"
+config LIMIT_HT_SPEED_1000
+ bool "Limit HT frequency to 1.0GHz"
+config LIMIT_HT_SPEED_1200
+ bool "Limit HT frequency to 1.2GHz"
+config LIMIT_HT_SPEED_1400
+ bool "Limit HT frequency to 1.4GHz"
+config LIMIT_HT_SPEED_1600
+ bool "Limit HT frequency to 1.6GHz"
+config LIMIT_HT_SPEED_1800
+ bool "Limit HT frequency to 1.8GHz"
+config LIMIT_HT_SPEED_2000
+ bool "Limit HT frequency to 2.0GHz"
+config LIMIT_HT_SPEED_2200
+ bool "Limit HT frequency to 2.2GHz"
+config LIMIT_HT_SPEED_2400
+ bool "Limit HT frequency to 2.4GHz"
+config LIMIT_HT_SPEED_2600
+ bool "Limit HT frequency to 2.6GHz"
+config LIMIT_HT_SPEED_AUTO
+ bool "Autodetect HT frequency"
+endchoice
+
+choice
+ prompt "HyperTransport downlink width"
+ default LIMIT_HT_DOWN_WIDTH_16
+ help
+ This option sets the maximum permissible HyperTransport
+ downlink width.
+
+ Use of this option will only limit the autodetected HT width.
+ It will not (and cannot) increase the width beyond the autodetected
+ limits.
+
+ This is primarily used to work around poorly designed or laid out HT
+ traces on certain motherboards.
+
+config LIMIT_HT_DOWN_WIDTH_8
+ bool "8 bits"
+config LIMIT_HT_DOWN_WIDTH_16
+ bool "16 bits"
+endchoice
+
+choice
+ prompt "HyperTransport uplink width"
+ default LIMIT_HT_UP_WIDTH_16
+ help
+ This option sets the maximum permissible HyperTransport
+ uplink width.
+
+ Use of this option will only limit the autodetected HT width.
+ It will not (and cannot) increase the width beyond the autodetected
+ limits.
+
+ This is primarily used to work around poorly designed or laid out HT
+ traces on certain motherboards.
+
+config LIMIT_HT_UP_WIDTH_8
+ bool "8 bits"
+config LIMIT_HT_UP_WIDTH_16
+ bool "16 bits"
+endchoice
+
+config AMDMCT_ENABLE_ECC_REDIR
+ bool
+ depends on CPU_AMD_MODEL_10XXX
+ default n
+
+config AMDMCT_BACKGROUND_SCRUB_RATE
+ hex
+ depends on CPU_AMD_MODEL_10XXX
+ default 0x00
+ help
+ This option sets the background ECC memory scub rate
+
+ Permissible values are:
+
+ 0x00; Disabled
+ 0x01; 40ns
+ 0x02; 80ns
+ 0x03; 160ns
+ 0x04; 320ns
+ 0x05; 640ns
+ 0x06; 1.28us
+ 0x07; 2.56us
+ 0x08; 5.12us
+ 0x09; 10.2us
+ 0x0a; 20.5us
+ 0x0b; 41us
+ 0x0c; 81.9us
+ 0x0d; 163.8us
+ 0x0e; 327.7us
+ 0x0f; 655.4us
+ 0x10; 1.31ms
+ 0x11; 2.62ms
+ 0x12; 5.24ms
+ 0x13; 10.49ms
+ 0x14; 20.97sms
+ 0x15; 42ms
+ 0x16; 84ms
+
+endmenu
+
endif # NORTHBRIDGE_AMD_AMDFAM10
Timothy Pearson (tpearson(a)raptorengineeringinc.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8405
-gerrit
commit e0ab9f93a561bc932b85bc065f5382771954991f
Author: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
Date: Thu Feb 12 01:27:06 2015 -0600
northbridge/amd/amdfam10: Allow mainboards to set maximum HT link frequency
Most K10 mainboards are designed to a maximum HT frequency specification.
Coreboot supports CPUs that were released after mainboard production;
these CPUs may support and autodetect HT link frequencies beyond the
mainboard design capabilities. This patch allows mainboards to set
an HT frequency limit if needed.
Moved K10 specific menu to amdfam10 Kconfig file.
Change-Id: If7ff40dccb4c22829062511ca0046aa2caf15580
Signed-off-by: Timothy Pearson <tpearson(a)raptorengineeringinc.com>
---
src/northbridge/amd/amdfam10/Kconfig | 83 +++++++++++++++++++++++++++++++++---
1 file changed, 78 insertions(+), 5 deletions(-)
diff --git a/src/northbridge/amd/amdfam10/Kconfig b/src/northbridge/amd/amdfam10/Kconfig
index 1c78590..35a683e 100644
--- a/src/northbridge/amd/amdfam10/Kconfig
+++ b/src/northbridge/amd/amdfam10/Kconfig
@@ -124,13 +124,88 @@ config SVI_HIGH_FREQ
Select this for boards with a Voltage Regulator able to operate
at 3.4 MHz in SVI mode. Ignored unless the AMD CPU is rev C3.
+config FORCE_LIMIT_HT_SPEED_200
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_300
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_400
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_500
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_600
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_800
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_1000
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_1200
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_1400
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_1600
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_1800
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_2000
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_2200
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_2400
+ bool
+ default n
+
+config FORCE_LIMIT_HT_SPEED_2600
+ bool
+ default n
+
menu "HyperTransport setup"
- #could be implemented for K8 (NORTHBRIDGE_AMD_AMDK8)
- depends on (NORTHBRIDGE_AMD_AMDFAM10) && EXPERT
+ # FIXME uncomment when coreboot gains "visible if" support
+ # visible if EXPERT
choice
prompt "HyperTransport frequency"
- default LIMIT_HT_SPEED_AUTO
+ default LIMIT_HT_SPEED_AUTO if (!FORCE_LIMIT_HT_SPEED_200 && !FORCE_LIMIT_HT_SPEED_300 && !FORCE_LIMIT_HT_SPEED_400 && !FORCE_LIMIT_HT_SPEED_500 && !FORCE_LIMIT_HT_SPEED_600 && !FORCE_LIMIT_HT_SPEED_800 && !FORCE_LIMIT_HT_SPEED_1000 && !FORCE_LIMIT_HT_SPEED_1200 && !FORCE_LIMIT_HT_SPEED_1400 && !FORCE_LIMIT_HT_SPEED_1600 && !FORCE_LIMIT_HT_SPEED_1800 && !FORCE_LIMIT_HT_SPEED_2000 && !FORCE_LIMIT_HT_SPEED_2200 && !FORCE_LIMIT_HT_SPEED_2400 && !FORCE_LIMIT_HT_SPEED_2600)
+ default LIMIT_HT_SPEED_200 if FORCE_LIMIT_HT_SPEED_200
+ default LIMIT_HT_SPEED_300 if FORCE_LIMIT_HT_SPEED_300
+ default LIMIT_HT_SPEED_400 if FORCE_LIMIT_HT_SPEED_400
+ default LIMIT_HT_SPEED_500 if FORCE_LIMIT_HT_SPEED_500
+ default LIMIT_HT_SPEED_600 if FORCE_LIMIT_HT_SPEED_600
+ default LIMIT_HT_SPEED_800 if FORCE_LIMIT_HT_SPEED_800
+ default LIMIT_HT_SPEED_1000 if FORCE_LIMIT_HT_SPEED_1000
+ default LIMIT_HT_SPEED_1200 if FORCE_LIMIT_HT_SPEED_1200
+ default LIMIT_HT_SPEED_1400 if FORCE_LIMIT_HT_SPEED_1400
+ default LIMIT_HT_SPEED_1600 if FORCE_LIMIT_HT_SPEED_1600
+ default LIMIT_HT_SPEED_1800 if FORCE_LIMIT_HT_SPEED_1800
+ default LIMIT_HT_SPEED_2000 if FORCE_LIMIT_HT_SPEED_2000
+ default LIMIT_HT_SPEED_2200 if FORCE_LIMIT_HT_SPEED_2200
+ default LIMIT_HT_SPEED_2400 if FORCE_LIMIT_HT_SPEED_2400
+ default LIMIT_HT_SPEED_2600 if FORCE_LIMIT_HT_SPEED_2600
help
This option sets the maximum permissible HyperTransport link
frequency.
@@ -218,12 +293,10 @@ endchoice
config AMDMCT_ENABLE_ECC_REDIR
bool
- depends on CPU_AMD_MODEL_10XXX
default n
config AMDMCT_BACKGROUND_SCRUB_RATE
hex
- depends on CPU_AMD_MODEL_10XXX
default 0x00
help
This option sets the background ECC memory scub rate
Werner Zeh (werner.zeh(a)siemens.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8404
-gerrit
commit ff2e25aa1595ed20e9cbdae3b88aaa9622e39302
Author: Werner Zeh <werner.zeh(a)siemens.com>
Date: Tue Feb 10 15:09:00 2015 +0100
drivers/intel/i210: Add new driver for Intel i210 MACPHY
Add a new driver for Intel i210 MACPHY with the goal to
update the MAC address in i210 if it is found
during PCI scan.
Change-Id: I4d4e797543a9f278fb649596f63ae8e1f285b3c3
Signed-off-by: Werner Zeh <werner.zeh(a)siemens.com>
---
src/drivers/intel/Kconfig | 1 +
src/drivers/intel/Makefile.inc | 1 +
src/drivers/intel/i210/Kconfig | 3 +
src/drivers/intel/i210/Makefile.inc | 1 +
src/drivers/intel/i210/i210.c | 241 ++++++++++++++++++++++++++++++++++++
src/drivers/intel/i210/i210.h | 56 +++++++++
6 files changed, 303 insertions(+)
diff --git a/src/drivers/intel/Kconfig b/src/drivers/intel/Kconfig
index 9954f31..511cf5c 100644
--- a/src/drivers/intel/Kconfig
+++ b/src/drivers/intel/Kconfig
@@ -18,3 +18,4 @@
##
source src/drivers/intel/gma/Kconfig
+source src/drivers/intel/i210/Kconfig
diff --git a/src/drivers/intel/Makefile.inc b/src/drivers/intel/Makefile.inc
index 7bc6dd5..6cf8f00 100644
--- a/src/drivers/intel/Makefile.inc
+++ b/src/drivers/intel/Makefile.inc
@@ -1,3 +1,4 @@
subdirs-y += gma
subdirs-y += wifi
subdirs-$(CONFIG_PLATFORM_USES_FSP) += fsp
+subdirs-$(CONFIG_DRIVER_INTEL_I210) += i210
\ No newline at end of file
diff --git a/src/drivers/intel/i210/Kconfig b/src/drivers/intel/i210/Kconfig
new file mode 100644
index 0000000..77d30e9
--- /dev/null
+++ b/src/drivers/intel/i210/Kconfig
@@ -0,0 +1,3 @@
+config CONFIG_DRIVER_INTEL_I210
+ bool
+ default n
\ No newline at end of file
diff --git a/src/drivers/intel/i210/Makefile.inc b/src/drivers/intel/i210/Makefile.inc
new file mode 100644
index 0000000..a1f15de
--- /dev/null
+++ b/src/drivers/intel/i210/Makefile.inc
@@ -0,0 +1 @@
+ramstage-y += i210.c
\ No newline at end of file
diff --git a/src/drivers/intel/i210/i210.c b/src/drivers/intel/i210/i210.c
new file mode 100644
index 0000000..76326a8
--- /dev/null
+++ b/src/drivers/intel/i210/i210.c
@@ -0,0 +1,241 @@
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "i210.h"
+#include <device/device.h>
+#include <console/console.h>
+#include <string.h>
+#include <types.h>
+
+/* We need one function we can call to get a MAC address to use */
+/* This function can be coded somewhere else but must exist. */
+extern enum cb_err get_mac_address(u32 pci_bdf, u8 mac[6]);
+
+/* This is a private function to wait for a bit mask in a given register */
+/* To avoid endless loops, a time-out is implemented here. */
+static int wait_done(u32* reg, u32 mask)
+{
+ u32 timeout = I210_POLL_TIMEOUT_US;
+ do {
+ if (!(*reg & mask)) {
+ udelay(1);
+ timeout--;
+ }
+ } while((!(*reg & mask)) && timeout);
+ return timeout ? I210_NO_ERROR : I210_NOT_READY;
+}
+
+/** \brief This function is the driver entry point for the init phase
+ * of the PCI bus allocator. It will program a MAC address
+ * into the MACPHY.
+ * @param *dev Pointer to the used PCI device
+ * @return void Nothing is given back
+ */
+static void init(struct device *dev)
+{
+ u8 cur_adr[6];
+ u8 adr_to_set[6];
+ enum cb_err status;
+
+ /*Check first whether there is a valid MAC address available */
+ status = get_mac_address((dev->bus->subordinate << 16) |
+ dev->path.pci.devfn << 8, adr_to_set);
+ if (status != CB_SUCCESS) {
+ printk(BIOS_ERR, "I210: No valid MAC address found\n");
+ return;
+ }
+ /* Before we will write a new address, check the existing one */
+ if (read_mac_adr(dev, cur_adr)) {
+ printk(BIOS_ERR, "I210: Not able to read MAC address.\n");
+ return;
+ }
+ if (memcmp(cur_adr, adr_to_set, 6)) {
+ if (write_mac_adr(dev, adr_to_set)) {
+ printk(BIOS_ERR, "I210: Error setting MAC address\n");
+ } else {
+ printk(BIOS_INFO, "I210: MAC address changed.\n");
+ }
+ } else {
+ printk(BIOS_INFO, "I210: MAC address is up to date.\n");
+ }
+ return;
+}
+
+/** \brief This function can read the MAC address out of the MACPHY
+ * @param *dev Pointer to the PCI device of this MACPHY
+ * @param *MACAdr Pointer to the buffer where to store read MAC address
+ * @return void I210_NO_ERROR or an error code
+ */
+static u32 read_mac_adr(struct device *dev, u8 *MACAdr)
+{
+ u16 adr[3];
+ if (!dev || !MACAdr)
+ return I210_INVALID_PARAM;
+ if (read_flash(dev, 0, 3, adr))
+ return I210_READ_ERROR;
+ /* Copy the address into destination. This is done because of */
+ /* possible not matching alignment for destination to u16 boundary. */
+ memcpy(MACAdr, (u8*)adr, 6);
+ return I210_NO_ERROR;
+}
+
+/** \brief This function can write the MAC address to the MACPHY
+ * @param *dev Pointer to the PCI device of this MACPHY
+ * @param *MACAdr Pointer to the buffer where the desired MAC address is
+ * @return void I210_NO_ERROR or an error code
+ */
+static u32 write_mac_adr(struct device *dev, u8 *MACAdr)
+{
+ u16 adr[3];
+ if (!dev || !MACAdr)
+ return I210_INVALID_PARAM;
+ /* Copy desired address into a local buffer to avoid alignment issues */
+ memcpy((u8*)adr, MACAdr, 6);
+ return write_flash(dev, 0, 3, adr);
+}
+
+/** \brief This function can read the configuration space of the MACPHY
+ * For this purpose, the EEPROM interface is used. No direct access
+ * to the flash memory will be done.
+ * @param *dev Pointer to the PCI device of this MACPHY
+ * @param address Address inside the flash where reading will start
+ * @param count Number of words (16 bit values) to read
+ * @param *buffer Pointer to the buffer where to store read data
+ * @return void I210_NO_ERROR or an error code
+ */
+static u32 read_flash(struct device *dev, u32 address, u32 count, u16 *buffer)
+{
+ u32 bar;
+ u32 *eeprd;
+ u32 i;
+
+ /* Get the BAR to memory mapped space*/
+ bar = pci_read_config32(dev, 0x10);
+ if ((!bar) || ((address + count) > 0x40))
+ return I210_INVALID_PARAM;
+ eeprd = (u32*)(bar + I210_REG_EEREAD);
+ /* Prior to start ensure flash interface is ready by checking DONE-bit */
+ if (wait_done(eeprd, I210_DONE))
+ return I210_NOT_READY;
+
+ /*OK, interface is ready, we can use it now */
+ for (i = 0; i < count; i++) {
+ /* To start a read cycle write desired address in bits 12..2 */
+ *eeprd = ((address + i) << 2) & 0x1FFC;
+ /* Wait until read is done */
+ if (wait_done(eeprd, I210_DONE))
+ return I210_READ_ERROR;
+ /* Here, we can read back desired word in bits 31..16 */
+ buffer[i] = (*eeprd & 0xffff0000) >> 16;
+ }
+ return I210_NO_ERROR;
+}
+
+/** \brief This function can write the configuration space of the MACPHY
+ * For this purpose, the EEPROM interface is used. No direct access
+ * to the flash memory will be done. This function will update
+ * the checksum after a value was changed.
+ * @param *dev Pointer to the PCI device of this MACPHY
+ * @param address Address inside the flash where writing will start
+ * @param count Number of words (16 bit values) to write
+ * @param *buffer Pointer to the buffer where data to write is stored in
+ * @return void I210_NO_ERROR or an error code
+ */
+static u32 write_flash(struct device *dev, u32 address, u32 count, u16 *buffer)
+{
+ u32 bar;
+ u32 *eepwr;
+ u32 *eectrl;
+ u16 checksum;
+ u32 i;
+
+ /* Get the BAR to memory mapped space */
+ bar = pci_read_config32(dev, 0x10);
+ if ((!bar) || ((address + count) > 0x40))
+ return I210_INVALID_PARAM;
+ eepwr = (u32*)(bar + I210_REG_EEWRITE);
+ eectrl = (u32*)(bar + I210_REG_EECTRL);
+ /* Prior to start ensure flash interface is ready by checking DONE-bit */
+ if (wait_done(eepwr, I210_DONE))
+ return I210_NOT_READY;
+
+ /* OK, interface is ready, we can use it now */
+ for (i = 0; i < count; i++) {
+ /* To start a write cycle write desired address in bits 12..2 */
+ /* and data to write in bits 31..16 into EEWRITE-register */
+ *eepwr = ((((address + i) << 2) & 0x1FFC) | (buffer[i] << 16));
+ /* Wait until write is done */
+ if (wait_done(eepwr, I210_DONE))
+ return I210_WRITE_ERROR;
+ }
+ /* Since we have modified data, we need to update the checksum */
+ if (compute_checksum(dev, &checksum))
+ return I210_CHECKSUM_ERROR;
+ *eepwr = (0x3f << 2) | checksum << 16;
+ if (wait_done(eepwr, I210_DONE))
+ return I210_WRITE_ERROR;
+ /* Up to now, desired data was written into shadowed RAM. We now need */
+ /* to perform a flash cycle to bring the shadowed RAM into flash memory. */
+ /* To start a flash cycle we need to set FLUPD-bit and wait for FLDONE. */
+ *eectrl = *eectrl | I210_FLUPD;
+ if (wait_done(eectrl, I210_FLUDONE))
+ return I210_FLASH_UPDATE_ERROR;
+ else
+ return I210_NO_ERROR;
+}
+
+/** \brief This function computes the checksum for the configuration space.
+ * The address range for the checksum is 0x00..0x3e.
+ * @param *dev Pointer to the PCI device of this MACPHY
+ * @param *checksum Pointer to the buffer where to store the checksum
+ * @return void I210_NO_ERROR or an error code
+ */
+static u32 compute_checksum(struct device *dev, u16 *checksum)
+{
+ u16 eep_data[0x40];
+ u32 i;
+
+ /* First read back data to compute the checksum for */
+ if (read_flash(dev, 0, 0x3f, eep_data))
+ return I210_READ_ERROR;
+ /* The checksum is computed in that way that after summarize all the */
+ /* data from word address 0 to 0x3f the result is 0xBABA. */
+ *checksum = 0;
+ for (i = 0; i < 0x3f; i++)
+ *checksum += eep_data[i];
+ *checksum = I210_TARGET_CHECKSUM - *checksum;
+ return I210_NO_ERROR;
+}
+
+static struct device_operations i210_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = init,
+ .scan_bus = 0,
+ .ops_pci = 0,
+};
+
+static const unsigned short i210_device_ids[] = { 0x1538, 0x1533, 0 };
+
+static const struct pci_driver i210_driver __pci_driver = {
+ .ops = &i210_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .devices = i210_device_ids,
+};
diff --git a/src/drivers/intel/i210/i210.h b/src/drivers/intel/i210/i210.h
new file mode 100644
index 0000000..c1fd58a
--- /dev/null
+++ b/src/drivers/intel/i210/i210.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _INTEL_I210_H_
+#define _INTEL_I210_H_
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <delay.h>
+
+#define I210_PCI_MEM_BAR_OFFSET 0x10
+#define I210_REG_EECTRL 0x12010 /* Offset for EEPROM control reg */
+#define I210_FLUPD 0x800000 /* Start flash update bit */
+#define I210_FLUDONE 0x4000000 /* Flash update done indicator */
+#define I210_REG_EEREAD 0x12014 /* Offset for EEPROM read reg */
+#define I210_REG_EEWRITE 0x12018 /* Offset for EEPROM write reg */
+#define I210_CMDV 0x01 /* command valid bit */
+#define I210_DONE 0x02 /* command done bit */
+#define I210_TARGET_CHECKSUM 0xBABA /* resulting checksum */
+
+
+/*define some other useful values here */
+#define I210_POLL_TIMEOUT_US 300000 /* 300 ms */
+/*Define some error states here*/
+#define I210_NO_ERROR 0x00000000
+#define I210_INVALID_PARAM 0x00000001
+#define I210_NOT_READY 0x00000002
+#define I210_READ_ERROR 0x00000004
+#define I210_WRITE_ERROR 0x00000008
+#define I210_CHECKSUM_ERROR 0x00000010
+#define I210_FLASH_UPDATE_ERROR 0x00000020
+
+static void init(struct device *dev);
+static u32 read_mac_adr(struct device *dev, u8 *MACAdr);
+static u32 write_mac_adr(struct device *dev, u8 *MACAdr);
+static u32 read_flash(struct device *dev, u32 address, u32 count, u16 *buffer);
+static u32 write_flash(struct device *dev, u32 address, u32 count, u16 *buffer);
+static u32 compute_checksum(struct device *dev, u16 *checksum);
+
+#endif /* _INTEL_I210_H_ */
Werner Zeh (werner.zeh(a)siemens.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8401
-gerrit
commit a1fc29864aefe0fadb5245eac5d6292699d9779a
Author: Werner Zeh <werner.zeh(a)siemens.com>
Date: Tue Feb 10 13:02:34 2015 +0100
fsp_baytrail: Add I2C driver
Add a driver wich can handle the internal I2C controllers
of Baytrail SoC. This driver is not suitable for the
SMBUS-controller.
Change-Id: I841c3991a2fb0f8b92b8e59ec02d62f5866f5bdf
Signed-off-by: Werner Zeh <werner.zeh(a)siemens.com>
---
src/soc/intel/fsp_baytrail/Makefile.inc | 1 +
src/soc/intel/fsp_baytrail/baytrail/i2c.h | 136 +++++++++++++++
src/soc/intel/fsp_baytrail/i2c.c | 269 ++++++++++++++++++++++++++++++
3 files changed, 406 insertions(+)
diff --git a/src/soc/intel/fsp_baytrail/Makefile.inc b/src/soc/intel/fsp_baytrail/Makefile.inc
index 3896e85..2dfb9cb 100644
--- a/src/soc/intel/fsp_baytrail/Makefile.inc
+++ b/src/soc/intel/fsp_baytrail/Makefile.inc
@@ -54,6 +54,7 @@ smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c
ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smm.c
ramstage-y += placeholders.c
+ramstage-y += i2c.c
CPPFLAGS_common += -I$(src)/soc/intel/fsp_baytrail/
CPPFLAGS_common += -I$(src)/soc/intel/fsp_baytrail/fsp
diff --git a/src/soc/intel/fsp_baytrail/baytrail/i2c.h b/src/soc/intel/fsp_baytrail/baytrail/i2c.h
new file mode 100644
index 0000000..0c0e1bf
--- /dev/null
+++ b/src/soc/intel/fsp_baytrail/baytrail/i2c.h
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __SOC_INTEL_FSP_BAYTRAIL_I2C_H__
+#define __SOC_INTEL_FSP_BAYTRAIL_I2C_H__
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/pci_ids.h>
+#include <device/pci_def.h>
+
+/* SMBus controller settings in PCI configuration space */
+#define I2C_PCI_VENDOR_ID 0x8086
+#define I2C0_PCI_DEV_ID 0x0f41
+#define I2C1_PCI_DEV_ID 0x0f42
+#define I2C2_PCI_DEV_ID 0x0f43
+#define I2C3_PCI_DEV_ID 0x0f44
+#define I2C4_PCI_DEV_ID 0x0f45
+#define I2C5_PCI_DEV_ID 0x0f46
+#define I2C6_PCI_DEV_ID 0x0f47
+
+#define I2C0_MEM_BASE 0xd0921000
+#define I2C1_MEM_BASE 0xd0923000
+#define I2C2_MEM_BASE 0xd0925000
+#define I2C3_MEM_BASE 0xd0927000
+#define I2C4_MEM_BASE 0xd0929000
+#define I2C5_MEM_BASE 0xd092b000
+#define I2C6_MEM_BASE 0xd092d000
+
+#define I2C_STANDARD_MODE 0x1
+#define I2C_FAST_MODE 0x2
+
+/* Define relevant registers in PCI space */
+#define I2C_PCI_COMMAND 0x4
+#define I2C_PCI_STATUS 0x6
+
+/* Define memory mapped registers */
+#define I2C_CTRL 0x0
+#define I2C_SLAVE_DISABLE 0x40
+#define I2C_RESTART_EN 0x20
+#define I2C_ADR_MODE 0x10
+#define I2C_SPEED_MASK 0x6
+#define I2C_STD_MODE 0x1
+#define I2C_FAST_MODE 0x2
+#define I2C_MASTER_ENABLE 0x1
+
+#define I2C_TARGET_ADR 0x4
+#define I2C_TARGET_ADR_MASK 0x3ff
+
+#define I2C_DATA_CMD 0x10
+#define I2C_RESTART 0x400
+#define I2C_STOP 0x200
+#define I2C_RW_CMD 0x100
+
+#define I2C_SS_SCL_HCNT 0x14 /* Counter for high period for 100 kHz SCL */
+#define I2C_SS_SCL_LCNT 0x18 /* Counter for low period for 100 kHz SCL */
+#define I2C_FS_SCL_HCNT 0x1c /* Counter for high period for 400 kHz SCL */
+#define I2C_FS_SCL_LCNT 0x20 /* Counter for low period for 400 kHz SCL */
+
+#define I2C_INTR_STAT 0x2c /* Interrupt status register, read only */
+#define I2C_INTR_MASK 0x30 /* Interrupt mask register */
+#define I2C_RAW_INTR_STAT 0x34 /* Raw interrupt status, read only */
+#define I2C_START_DETECT 0x400
+#define I2C_STOP_DETECT 0x200
+#define I2C_ACTIVITY 0x100
+#define I2C_TX_ABORT 0x40
+#define I2C_RD_REQ 0x20 /* Read request in slave mode */
+#define I2C_TX_EMPTY 0x10
+#define I2C_TX_OVERFLOW 0x8
+#define I2C_RX_FULL 0x4
+#define I2C_RX_OVERFLOW 0x2
+#define I2C_RX_UNDERFLOW 0x1
+
+#define I2C_RX_TL 0x38 /* Rx FIFO threshold level 0..255 */
+#define I2C_TX_TL 0x3c /* Tx FIFO threshold level 0..255 */
+#define I2C_CLR_INTR 0x40 /* Clear all events with a read */
+#define I2C_CLR_TX_ABRT 0x54 /* Clear TX-Abort event with a read */
+
+/* There are a bunch of interrupt clearing registers now which are not used! */
+/* So proceed somewhat later with definition*/
+#define I2C_ENABLE 0x6c /* 0: disable I2C controller, 1: enable */
+#define I2C_STATUS 0x70
+#define I2C_MST_ACTIVITY 0x20 /* Master FSM activity */
+#define I2C_RFF 0x10 /* Receive FIFO completely full */
+#define I2C_RFNE 0x8 /* Receive FIFO not empty */
+#define I2C_TFE 0x4 /* Transmit FIFO completely empty */
+#define I2C_TFNF 0x2 /* Transmit FIFO not full */
+#define I2C_ACTIVE 0x1 /* 1: I2C currently in operation */
+
+#define I2C_TXFLR 0x74 /* Current transmit FIFO level */
+#define I2C_RXFLR 0x78 /* Current receive FIFO level */
+#define I2C_SDA_HOLD 0x7c /* Data hold time after SCL goes low */
+#define I2C_ABORT_SOURCE 0x80
+#define I2C_ARB_LOST 0x1000 /* Arbitration lost */
+#define I2C_MASTER_DIS 0x800 /* Master was disabled by user */
+#define I2C_10B_RD_NORSTRT 0x400 /* 10 bit address read and RESTART disabled */
+#define I2C_SBYTE_NORSTRT 0x200 /* START with RESTART disabled */
+#define I2C_START_ACKDET 0x80 /* START byte was acknowledged */
+#define I2C_TX_DATA_NOACK 0x8 /* TX data not acknowledged */
+#define I2C_10B_ADR2_NOACK 0x4 /* Second address byte in 10 bit mode NACK */
+#define I2C_10B_ADR1_NOACK 0x2 /* First address byte in 10 bit NACK */
+#define I2C_7B_ADDR_NACK 0x1 /* 7 bit address byte not acknowledged */
+
+#define I2C_ENABLE_STATUS 0x9c
+
+/* Define some status and error values*/
+#define I2C_ERR_INVALID_ADR 0x1000000
+#define I2C_ERR_TIMEOUT 0x2000000
+#define I2C_ERR_ABORT 0x4000000
+#define I2C_NO_ERROR 0x0000000
+
+
+#define I2C_TIMEOUT 2000 /* Use 2000 us as time*/
+
+/* Prototype section*/
+int i2c_init(unsigned bus);
+int i2c_read(unsigned bus, unsigned chip, unsigned addr, uint8_t *buf, unsigned len);
+int i2c_write(unsigned bus, unsigned chip, unsigned addr, const uint8_t *buf, unsigned len);
+
+#endif /* __SOC_INTEL_FSP_BAYTRAIL_I2C_H__ */
diff --git a/src/soc/intel/fsp_baytrail/i2c.c b/src/soc/intel/fsp_baytrail/i2c.c
new file mode 100644
index 0000000..dcd249b
--- /dev/null
+++ b/src/soc/intel/fsp_baytrail/i2c.c
@@ -0,0 +1,269 @@
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/pci.h>
+#include <baytrail/baytrail.h>
+#include <baytrail/pci_devs.h>
+#include <baytrail/iosf.h>
+#include <delay.h>
+#include <baytrail/i2c.h>
+
+/* Wait for the transmit FIFO till there is at least one slot empty.
+ * FIFO stall due to transmit abort will be checked and resolved
+ */
+static int wait_tx_fifo(char *base_adr) {
+ int i;
+
+ if (*((unsigned int *)(base_adr + I2C_ABORT_SOURCE)) & 0x1ffff) {
+ /* Reading back I2C_CLR_TX_ABRT resets abort lock on TX FIFO */
+ i = *((volatile unsigned int *)(base_adr + I2C_CLR_TX_ABRT));
+ return I2C_ERR_ABORT |
+ (*((unsigned int *)(base_adr + I2C_ABORT_SOURCE)) & 0x1ffff);
+ }
+
+ /* Wait here for a free slot in TX-FIFO */
+ i = I2C_TIMEOUT;
+ while ((!(*((volatile unsigned int *)(base_adr + I2C_STATUS)) & I2C_TFNF))
+ && (i)) {
+ udelay(1);
+ i--;
+ }
+
+ if (i == 0) {
+ return I2C_ERR_TIMEOUT;
+ } else {
+ return I2C_NO_ERROR;
+ }
+}
+
+/* Wait for the receive FIFO till there is at least one valid entry to read.
+ * FIFO stall due to transmit abort will be checked and resolved
+ */
+static int wait_rx_fifo(char *base_adr) {
+ int i;
+
+ if (*((unsigned int *)(base_adr + I2C_ABORT_SOURCE)) & 0x1ffff) {
+ /* Reading back I2C_CLR_TX_ABRT resets abort lock on TX FIFO */
+ i = *((volatile unsigned int *)(base_adr + I2C_CLR_TX_ABRT));
+ return I2C_ERR_ABORT |
+ (*((unsigned int *)(base_adr + I2C_ABORT_SOURCE)) & 0x1ffff);
+ }
+
+ /* Wait here for a received entry in RX-FIFO */
+ i = I2C_TIMEOUT;
+ while ((!(*((volatile unsigned int *)(base_adr + I2C_STATUS)) & I2C_RFNE))
+ && (i)) {
+ udelay(1);
+ i--;
+ }
+
+ if (i == 0) {
+ return I2C_ERR_TIMEOUT;
+ } else {
+ return I2C_NO_ERROR;
+ }
+}
+
+/* When there will be a fast switch between send and receive, one have
+ * to wait until the first operation is completely finished
+ * before starting the second operation
+ */
+static int wait_for_idle(char *base_adr)
+{
+ int i;
+ volatile int status;
+
+ /* For IDLE, increase timeout by ten times */
+ i = I2C_TIMEOUT * 10;
+ status = *((volatile unsigned int *)(base_adr + I2C_STATUS));
+ while (((status & I2C_MST_ACTIVITY) || (!(status & I2C_TFE))) && (i)) {
+ status = *((volatile unsigned int *)(base_adr + I2C_STATUS));
+ udelay(1);
+ i--;
+ }
+
+ if (i == 0) {
+ return I2C_ERR_TIMEOUT;
+ } else {
+ return I2C_NO_ERROR;
+ }
+}
+
+/** \brief Enables I2C-controller, sets up BAR and timing parameters
+ * @param bus Number of the I2C-controller to use (0...6)
+ * @return 0 on success, otherwise error code
+ */
+int i2c_init(unsigned bus)
+{
+ device_t dev;
+ int base_adr[7] = {I2C0_MEM_BASE, I2C1_MEM_BASE, I2C2_MEM_BASE,
+ I2C3_MEM_BASE, I2C4_MEM_BASE, I2C5_MEM_BASE,
+ I2C6_MEM_BASE};
+ char *base_ptr = (char*)base_adr[bus];
+ /* Ensure the desired device is valid */
+ if (bus > 6) {
+ printk (BIOS_ERR, "I2C: Only I2C controllers 0...6 are available");
+ return 1;
+ }
+
+ /* Set the I2C-device the user wants to use */
+ dev = dev_find_slot(0, PCI_DEVFN(I2C1_DEV, bus + 1));
+
+ /* Ensure we have the right PCI device */
+ if ((pci_read_config16(dev, 0x0) != I2C_PCI_VENDOR_ID) ||
+ (pci_read_config16(dev, 0x2) != (I2C0_PCI_DEV_ID + bus))) {
+ printk(BIOS_ERR, "I2C: Controller %d not found!", bus);
+ return 2;
+ }
+
+ /* Set memory base */
+ pci_write_config32(dev, PCI_BASE_ADDRESS_0, (int)base_ptr);
+
+ /* Enable memory space */
+ pci_write_config32(dev, PCI_COMMAND,
+ (pci_read_config32(dev, PCI_COMMAND) | 0x2));
+
+ /* Set up some settings of I2C controller */
+ *((unsigned int *)(base_ptr + I2C_CTRL)) = (I2C_RESTART_EN |
+ (I2C_STANDARD_MODE << 1) |
+ I2C_MASTER_ENABLE);
+ /* Adjust frequency for standard mode to 100 kHz */
+ /* The counter value can be computed by N=100MHz/2/I2C_CLK */
+ /* Thus, for 100 kHz I2C_CLK, N is 0x1F4 */
+ *((unsigned int *)(base_ptr + I2C_SS_SCL_HCNT)) = 0x1f4;
+ *((unsigned int *)(base_ptr + I2C_SS_SCL_LCNT)) = 0x1f4;
+ /* For 400 kHz, the counter value is 0x7d */
+ *((unsigned int *)(base_ptr + I2C_FS_SCL_HCNT)) = 0x7d;
+ *((unsigned int *)(base_ptr + I2C_FS_SCL_LCNT)) = 0x7d;
+
+ /* Enable the I2C controller for operation */
+ *((unsigned int *)(base_ptr + I2C_ENABLE)) = 0x1;
+
+ printk(BIOS_INFO, "I2C: Controller %d enabled.\n", bus);
+ return I2C_NO_ERROR;
+}
+
+/** \brief Read bytes over I2C-Bus from a slave. This function tries only one
+ * time to transmit data. In case of an error (abort) error code is
+ * returned. Retransmission has to be done from caller!
+ * @param bus Number of the I2C-controller to use (0...6)
+ * @param chip 7 Bit of the slave address on I2C bus
+ * @param addr Address inside slave where to read from
+ * @param *buf Pointer to the buffer where to store read data
+ * @param len Number of bytes to read
+ * @return I2C_NO_ERROR when read was successful, otherwise error code
+ */
+int i2c_read(unsigned bus, unsigned chip, unsigned addr,
+ uint8_t *buf, unsigned len)
+{
+ int i = 0;
+ char *base_ptr = NULL;
+ device_t dev;
+ unsigned int val;
+ int stat;
+
+ /* Get base address of desired I2C-controller */
+ dev = dev_find_slot(0, PCI_DEVFN(I2C1_DEV, bus + 1));
+ base_ptr = (char *)pci_read_config32(dev, PCI_BASE_ADDRESS_0);
+ if (base_ptr == NULL) {
+ printk(BIOS_INFO, "I2C: Invalid Base address\n");
+ return I2C_ERR_INVALID_ADR;
+ }
+
+ /* Ensure I2C controller is not active before setting slave address */
+ stat = wait_for_idle(base_ptr);
+ if (stat != I2C_NO_ERROR) {
+ return stat;
+ }
+ /* Now we can program the desired slave address and start transfer */
+ *((unsigned int *)(base_ptr + I2C_TARGET_ADR)) = (chip & 0xff);
+ /* Send address inside slave to read from */
+ *((unsigned int *)(base_ptr + I2C_DATA_CMD)) = (addr & 0xff);
+
+ /* For the next byte we need a repeated start condition */
+ val = I2C_RW_CMD | I2C_RESTART;
+ /* Now we can read desired amount of data over I2C */
+ for (i = 0; i < len; i++) {
+ /* A read is initiated by writing dummy data to the DATA-register */
+ *((unsigned int *)(base_ptr + I2C_DATA_CMD)) = val;
+ stat = wait_rx_fifo(base_ptr);
+ if (stat) {
+ return stat;
+ }
+ buf[i] = (*((unsigned int *)(base_ptr + I2C_DATA_CMD))) & 0xff;
+ val = I2C_RW_CMD;
+ if (i == (len -2)) {
+ /* For the last byte we need a stop condition to be generated */
+ val |= I2C_STOP;
+ }
+ }
+ return I2C_NO_ERROR;
+}
+
+/** \brief Write bytes over I2C-Bus from a slave. This function tries only one
+ * time to transmit data. In case of an error (abort) error code is
+ * returned. Retransmission has to be done from caller!
+ * @param bus Number of the I2C-controller to use (0...6)
+ * @param chip 7 Bit of the slave address on I2C bus
+ * @param addr Address inside slave where to write to
+ * @param *buf Pointer to the buffer where data to write is stored
+ * @param len Number of bytes to write
+ * @return I2C_NO_ERROR when read was successful, otherwise error code
+ */
+int i2c_write(unsigned bus, unsigned chip, unsigned addr,
+ const uint8_t *buf, unsigned len)
+{
+ int i;
+ char *base_ptr;
+ device_t dev;
+ unsigned int val;
+ int stat;
+
+ /* Get base address of desired I2C-controller */
+ dev = dev_find_slot(0, PCI_DEVFN(I2C1_DEV, bus + 1));
+ base_ptr = (char *)pci_read_config32(dev, PCI_BASE_ADDRESS_0);
+ if (base_ptr == NULL) {
+ return I2C_ERR_INVALID_ADR;
+ }
+
+ /* Ensure I2C controller is not active yet */
+ stat = wait_for_idle(base_ptr);
+ if (stat) {
+ return stat;
+ }
+ /* Program slave address to use for this transfer */
+ *((unsigned int *)(base_ptr + I2C_TARGET_ADR)) = (chip & 0xff);
+
+ /* Send address inside slave to write data to */
+ *((unsigned int *)(base_ptr + I2C_DATA_CMD)) = (addr & 0xff);
+
+ for (i = 0; i < len; i++) {
+ val = (unsigned int)(buf[i] & 0xff); /* Take only 8 bits */
+ if (i == (len -1)) {
+ /* For the last byte we need a stop condition */
+ val |= I2C_STOP;
+ }
+ stat = wait_tx_fifo(base_ptr);
+ if (stat) {
+ return stat;
+ }
+ *((unsigned int *)(base_ptr + I2C_DATA_CMD)) = val;
+ }
+ return I2C_NO_ERROR;
+}
Werner Zeh (werner.zeh(a)siemens.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8403
-gerrit
commit 58dafa805db85dec4211d4e7a4c22fe0805859aa
Author: Werner Zeh <werner.zeh(a)siemens.com>
Date: Tue Feb 10 14:34:17 2015 +0100
lint: exclude *.hex files from whitespace checking
If one needs raw binary files, .bin extension cannot
be used due to settings in .gitignore. This patch
allows to use .hex files. To avoid lint checks on these
files, exclude the .hex extension from the test.
Change-Id: I4b503229d63694c48cce12ca8cd33ea58172af01
Signed-off-by: Werner Zeh <werner.zeh(a)siemens.com>
---
util/lint/lint-stable-003-whitespace | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/util/lint/lint-stable-003-whitespace b/util/lint/lint-stable-003-whitespace
index 47853ba..f13aa98 100755
--- a/util/lint/lint-stable-003-whitespace
+++ b/util/lint/lint-stable-003-whitespace
@@ -19,6 +19,6 @@
# DESCR: Check for superfluous whitespace in the tree
LC_ALL=C export LC_ALL
-grep -l "[[:space:]][[:space:]]*$" `git ls-files src util |egrep -v "(^3rdparty|^src/vendorcode/|^util/kconfig/|^util/nvidia/cbootimage$|\<COPYING\>|\<LICENSE\>|\<README\>|_shipped$|\.patch|\.bin$)"` | \
+grep -l "[[:space:]][[:space:]]*$" `git ls-files src util |egrep -v "(^3rdparty|^src/vendorcode/|^util/kconfig/|^util/nvidia/cbootimage$|\<COPYING\>|\<LICENSE\>|\<README\>|_shipped$|\.patch$|\.bin$|\.hex$)"` | \
sed -e "s,^.*$,File & has lines ending with whitespace.,"
Werner Zeh (werner.zeh(a)siemens.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8372
-gerrit
commit d308e703dd19c921b06635212e5d749bb9dcd4a3
Author: Patrick Georgi <patrick(a)georgi-clan.de>
Date: Thu Feb 5 23:38:45 2015 +0100
lint: exclude nvidia submodule from file list
From git's point of view submodules are a weird third thing between file
and directory. Avoid trying to apply file handling on a directory.
Change-Id: Ibbc9c28e1657d96413c5fb08705d30e25171254d
Signed-off-by: Patrick Georgi <patrick(a)georgi-clan.de>
---
util/lint/lint-stable-003-whitespace | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/util/lint/lint-stable-003-whitespace b/util/lint/lint-stable-003-whitespace
index 22c5c3c..47853ba 100755
--- a/util/lint/lint-stable-003-whitespace
+++ b/util/lint/lint-stable-003-whitespace
@@ -19,6 +19,6 @@
# DESCR: Check for superfluous whitespace in the tree
LC_ALL=C export LC_ALL
-grep -l "[[:space:]][[:space:]]*$" `git ls-files src util |egrep -v "(^3rdparty|^src/vendorcode/|^util/kconfig/|\<COPYING\>|\<LICENSE\>|\<README\>|_shipped$|\.patch|\.bin$)"` | \
+grep -l "[[:space:]][[:space:]]*$" `git ls-files src util |egrep -v "(^3rdparty|^src/vendorcode/|^util/kconfig/|^util/nvidia/cbootimage$|\<COPYING\>|\<LICENSE\>|\<README\>|_shipped$|\.patch|\.bin$)"` | \
sed -e "s,^.*$,File & has lines ending with whitespace.,"