Gerd Hoffmann (kraxel(a)redhat.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8608
-gerrit
commit 68c7e659100c6247f2169df5766ba3f8d83b03b3
Author: Gerd Hoffmann <kraxel(a)redhat.com>
Date: Wed Aug 27 11:25:13 2014 +0200
qemu: 2.1+ smbios tables support
Starting with version 2.1 qemu provides a full set of smbios tables
for the virtual hardware emulated, except type 0 (bios information).
This patch adds support for loading those tables to coreboot.
The code is used by both i440fx and q35.
Change-Id: Id034f0c214e8890194145a92f06354201dee7963
Signed-off-by: Gerd Hoffmann <kraxel(a)redhat.com>
---
3rdparty | 2 +-
src/mainboard/emulation/qemu-i440fx/fw_cfg.c | 83 +++++++++++++++++++++++
src/mainboard/emulation/qemu-i440fx/fw_cfg.h | 1 +
src/mainboard/emulation/qemu-i440fx/northbridge.c | 5 ++
4 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/3rdparty b/3rdparty
index f42b78f..5eb7a9c 160000
--- a/3rdparty
+++ b/3rdparty
@@ -1 +1 @@
-Subproject commit f42b78f4f4df5ebc83f937f0dce4d348c9943a92
+Subproject commit 5eb7a9cf0897134f2fbe6d32b3b6e45b7981932f
diff --git a/src/mainboard/emulation/qemu-i440fx/fw_cfg.c b/src/mainboard/emulation/qemu-i440fx/fw_cfg.c
index 44256be..242f218 100644
--- a/src/mainboard/emulation/qemu-i440fx/fw_cfg.c
+++ b/src/mainboard/emulation/qemu-i440fx/fw_cfg.c
@@ -362,6 +362,89 @@ static void fw_cfg_smbios_init(void)
}
}
+static unsigned long smbios_next(unsigned long current)
+{
+ struct smbios_type0 *t0;
+ int l, count = 0;
+ char *s;
+
+ t0 = (void*)current;
+ current += t0->length;
+ for (;;) {
+ s = (void*)current;
+ l = strlen(s);
+ if (!l)
+ return current + (count ? 1 : 2);
+ current += l + 1;
+ count++;
+ }
+}
+
+/*
+ * Starting with version 2.1 qemu provides a full set of smbios tables
+ * for the virtual hardware emulated, except type 0 (bios information).
+ *
+ * What we are going to do here is find the type0 table, keep it, and
+ * override everything else generated by coreboot with the qemu smbios
+ * tables.
+ *
+ * It's a bit hackish, but qemu is a special case (compared to real
+ * hardware) and this way we don't need special qemu support in the
+ * generic smbios code.
+ */
+unsigned long fw_cfg_smbios_tables(int *handle, unsigned long *current)
+{
+ struct smbios_type0 *t0;
+ unsigned long start, end;
+ int len, ret, i, count = 1;
+ char *str;
+
+ len = fw_cfg_check_file("etc/smbios/smbios-tables");
+ if (len < 0)
+ return 0;
+ printk(BIOS_DEBUG, "QEMU: found smbios tables in fw_cfg (len %d).\n", len);
+
+ /*
+ * Search backwards for "coreboot" (first string in type0 table,
+ * see src/arch/x86/boot/smbios.c), then find type0 table.
+ */
+ for (i = 0; i < 16384; i++) {
+ str = (char*)(*current - i);
+ if (strcmp(str, "coreboot") == 0)
+ break;
+ }
+ if (i == 16384)
+ return 0;
+ i += sizeof(struct smbios_type0) - 2;
+ t0 = (struct smbios_type0*)(*current - i);
+ if (t0->type != SMBIOS_BIOS_INFORMATION || t0->handle != 0)
+ return 0;
+ printk(BIOS_DEBUG, "QEMU: coreboot type0 table found at 0x%lx.\n",
+ *current - i);
+ start = smbios_next(*current - i);
+
+ /*
+ * Fetch smbios tables from qemu, go find the end marker.
+ * We'll exclude the end marker as coreboot will add one.
+ */
+ printk(BIOS_DEBUG, "QEMU: loading smbios tables to 0x%lx\n", start);
+ fw_cfg_load_file("etc/smbios/smbios-tables", (void*)start);
+ end = start;
+ do {
+ t0 = (struct smbios_type0*)end;
+ if (t0->type == SMBIOS_END_OF_TABLE)
+ break;
+ end = smbios_next(end);
+ count++;
+ } while (end < start + len);
+
+ /* final fixups. */
+ ret = end - *current;
+ *current = end;
+ *handle = count;
+ return ret;
+}
+
const char *smbios_mainboard_manufacturer(void)
{
fw_cfg_smbios_init();
diff --git a/src/mainboard/emulation/qemu-i440fx/fw_cfg.h b/src/mainboard/emulation/qemu-i440fx/fw_cfg.h
index 2a10d8b..51ecaa8 100644
--- a/src/mainboard/emulation/qemu-i440fx/fw_cfg.h
+++ b/src/mainboard/emulation/qemu-i440fx/fw_cfg.h
@@ -19,3 +19,4 @@ void fw_cfg_get(int entry, void *dst, int dstlen);
int fw_cfg_check_file(const char *name);
void fw_cfg_load_file(const char *name, void *dst);
int fw_cfg_max_cpus(void);
+unsigned long fw_cfg_smbios_tables(int *handle, unsigned long *current);
diff --git a/src/mainboard/emulation/qemu-i440fx/northbridge.c b/src/mainboard/emulation/qemu-i440fx/northbridge.c
index 08d563f..f12a272 100644
--- a/src/mainboard/emulation/qemu-i440fx/northbridge.c
+++ b/src/mainboard/emulation/qemu-i440fx/northbridge.c
@@ -213,6 +213,11 @@ static int qemu_get_smbios_data17(int handle, int parent_handle, unsigned long *
static int qemu_get_smbios_data(device_t dev, int *handle, unsigned long *current)
{
int len;
+
+ len = fw_cfg_smbios_tables(handle, current);
+ if (len != 0)
+ return len;
+
len = qemu_get_smbios_data16(*handle, current);
len += qemu_get_smbios_data17(*handle+1, *handle, current);
*handle += 2;
the following patch was just integrated into master:
commit 1b770fb4b5a83042a6007cd9d263bfdf078822ad
Author: Patrick Georgi <pgeorgi(a)google.com>
Date: Wed Mar 4 15:03:05 2015 +0100
build system: Only setup git hooks if we're in a git checkout
A bit crude test, but before we would have _created_ .git
and confused later git presence tests.
Change-Id: Iec882d0e38ce1bd227cae8c1e541fb21be085290
Signed-off-by: Patrick Georgi <pgeorgi(a)google.com>
Reviewed-on: http://review.coreboot.org/8601
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
See http://review.coreboot.org/8601 for details.
-gerrit
the following patch was just integrated into master:
commit c0e394b7425b40c7d6c49d170054b71200d20515
Author: Patrick Georgi <pgeorgi(a)google.com>
Date: Wed Mar 4 15:02:03 2015 +0100
build system: Only test for git once
And then use the variable to decide what to do.
Change-Id: I48a801ecdbf774c4a8b64d7efaf9cf0ef2c2d438
Signed-off-by: Patrick Georgi <pgeorgi(a)google.com>
Reviewed-on: http://review.coreboot.org/8600
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
See http://review.coreboot.org/8600 for details.
-gerrit
the following patch was just integrated into master:
commit c42a613ff52d9cda91abaa5fa86ec4fd5b50aba6
Author: Werner Zeh <werner.zeh(a)siemens.com>
Date: Thu Feb 12 12:40:15 2015 +0100
mainboard/siemens/mc_tcu3: Add new mainboard.
This mainboard is based on Intel's Bayleybay
board which uses Bay Trail CPU with Intel FSP.
It has one USB3.0 interface, 4 USB2.0 interfaces,
up to two Ethernet ports and a LVDS connection
for LCD panels. The board is equipped with 512 MB
of DDR3 in a memory down configuration.
This board boots into Ubuntu/Lubuntu 14.10 using SeaBIOS,
but other OSes should work as well (but are not tested).
It has a version.hex file which is needed for
our OS and has no hardware functionality.
Change-Id: I94401bbd1d61ec69703de38ae1bc97969c5d979e
Signed-off-by: Werner Zeh <werner.zeh(a)siemens.com>
Reviewed-on: http://review.coreboot.org/8430
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi(a)google.com>
See http://review.coreboot.org/8430 for details.
-gerrit
the following patch was just integrated into master:
commit 0f9c9de35a84ce1d038e8f906a4b02b75f8e5869
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>
Reviewed-on: http://review.coreboot.org/8401
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi(a)google.com>
See http://review.coreboot.org/8401 for details.
-gerrit
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 07ab2c535005b6100b8bbf9f167328546d2d3bcb
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 | 138 ++++++++++++++++
src/soc/intel/fsp_baytrail/i2c.c | 257 ++++++++++++++++++++++++++++++
3 files changed, 396 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..5430dbe
--- /dev/null
+++ b/src/soc/intel/fsp_baytrail/baytrail/i2c.h
@@ -0,0 +1,138 @@
+/*
+ * 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>
+#include <stdlib.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_ERR 0x8000000
+#define I2C_SUCCESS 0x0000000
+
+
+#define I2C_TIMEOUT_US 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..1b13e03
--- /dev/null
+++ b/src/soc/intel/fsp_baytrail/i2c.c
@@ -0,0 +1,257 @@
+/*
+ * 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 (read32(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_US;
+ while ((!(*((volatile unsigned int *)(base_adr + I2C_STATUS)) & I2C_TFNF))) {
+ udelay(1);
+ if (!--i)
+ return I2C_ERR_TIMEOUT;
+ }
+
+ return I2C_SUCCESS;
+}
+
+/* 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 (read32(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_US;
+ while ((!(*((volatile unsigned int *)(base_adr + I2C_STATUS)) & I2C_RFNE))) {
+ udelay(1);
+ if (!--i)
+ return I2C_ERR_TIMEOUT;
+ }
+
+ return I2C_SUCCESS;
+}
+
+/* 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_US * 10;
+ status = *((volatile unsigned int *)(base_adr + I2C_STATUS));
+ while (((status & I2C_MST_ACTIVITY) || (!(status & I2C_TFE)))) {
+ status = *((volatile unsigned int *)(base_adr + I2C_STATUS));
+ udelay(1);
+ if (!--i)
+ return I2C_ERR_TIMEOUT;
+ }
+
+ return I2C_SUCCESS;
+
+}
+
+/** \brief Enables I2C-controller, sets up BAR and timing parameters
+ * @param bus Number of the I2C-controller to use (0...6)
+ * @return I2C_SUCCESS 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;
+ /* Ensure the desired device is valid */
+ if (bus > ARRAY_SIZE(base_adr)) {
+ printk(BIOS_ERR, "I2C: Only I2C controllers 0...6 are available.\n");
+ return I2C_ERR;
+ }
+
+ base_ptr = (char*)base_adr[bus];
+ /* 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!\n", bus);
+ return I2C_ERR;
+ }
+
+ /* 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_SUCCESS;
+}
+
+/** \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_SUCCESS 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_SUCCESS)
+ 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_SUCCESS;
+}
+
+/** \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_SUCCESS 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_SUCCESS;
+}
the following patch was just integrated into master:
commit b5a374d58befa96f718d0c2cee9afafb60867f18
Author: Werner Zeh <werner.zeh(a)siemens.com>
Date: Tue Feb 10 10:16:12 2015 +0100
fsp_baytrail: Add new microcode for Bay Trail M
Add a new microcode for Bay Trail M D0 stepping used
in cpu N2807 silicon.
In addition, a selection of the used CPU type has
been added (I or M/D) which allows to use only the
really needed microcode for a given CPU type.
Change-Id: I373fc9b535f1dc97eaa9f76ae46f0b69b247a8a0
Signed-off-by: Werner Zeh <werner.zeh(a)siemens.com>
Reviewed-on: http://review.coreboot.org/8399
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi(a)google.com>
See http://review.coreboot.org/8399 for details.
-gerrit