Kyösti Mälkki (kyosti.malkki(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8537
-gerrit
commit 78cdee7fef43498cf45655aa8af0c560559f0147
Author: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Date: Mon Feb 23 06:58:26 2015 +0200
PCI subsystem: Use subordinate property to track bus enumeration
Parameter max is the cumulative number of PCI buses scanned on the
system so far. Use the property subordinate from the parent PCI bridge
device to keep track of the first available bus number instead of
passing that on the stack.
Change-Id: I1a884c98d50fa4f1eb2752e10b778aea8a7b090a
Signed-off-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
---
src/device/pci_device.c | 29 +++++++++--------------------
1 file changed, 9 insertions(+), 20 deletions(-)
diff --git a/src/device/pci_device.c b/src/device/pci_device.c
index d3a7865..538ab4c 100644
--- a/src/device/pci_device.c
+++ b/src/device/pci_device.c
@@ -1179,11 +1179,16 @@ static void pci_bridge_route(struct bus *link, scan_state state)
struct bus *parent = dev->bus;
u32 reg, buses = 0;
+ if (state == PCI_ROUTE_SCAN) {
+ link->secondary = parent->subordinate + 1;
+ link->subordinate = link->secondary;
+ }
+
if (state == PCI_ROUTE_CLOSE) {
buses |= 0xfeff << 8;
} else if (state == PCI_ROUTE_SCAN) {
buses |= ((u32) link->secondary & 0xff) << 8;
- buses |= ((u32) link->subordinate & 0xff) << 16;
+ buses |= 0xff << 16; /* MAX PCI_BUS number here */
} else if (state == PCI_ROUTE_FINAL) {
buses |= parent->secondary & 0xff;
buses |= ((u32) link->secondary & 0xff) << 8;
@@ -1210,10 +1215,10 @@ static void pci_bridge_route(struct bus *link, scan_state state)
if (state == PCI_ROUTE_FINAL) {
pci_write_config16(dev, PCI_COMMAND, link->bridge_cmd);
+ parent->subordinate = link->subordinate;
}
}
-
/**
* Scan a PCI bridge and the buses behind the bridge.
*
@@ -1249,29 +1254,13 @@ unsigned int do_pci_scan_bridge(struct device *dev, unsigned int max,
bus = dev->link_list;
- /*
- * Set up the primary, secondary and subordinate bus numbers. We have
- * no idea how many buses are behind this bridge yet, so we set the
- * subordinate bus number to 0xff for the moment.
- */
- bus->secondary = ++max;
- bus->subordinate = 0xff;
-
pci_bridge_route(bus, PCI_ROUTE_SCAN);
- /* Now we can scan all subordinate buses (those behind the bridge). */
- max = do_scan_bus(bus, 0x00, 0xff, max);
-
- /*
- * We know the number of buses behind this bridge. Set the subordinate
- * bus number to its real value.
- */
- bus->subordinate = max;
+ bus->subordinate = do_scan_bus(bus, 0x00, 0xff, bus->secondary);
pci_bridge_route(bus, PCI_ROUTE_FINAL);
- printk(BIOS_SPEW, "%s returns max %d\n", __func__, max);
- return max;
+ return bus->subordinate;
}
/**
Kyösti Mälkki (kyosti.malkki(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8532
-gerrit
commit 572aaa100f7d1de2c8cb918c18c7f8d9eefc544a
Author: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
Date: Fri Feb 6 09:15:52 2015 +0200
devicetree: Drop dummy root_dev ops
This is just dead code.
Should we decide that we want some of these calls made, they would
be implemented in the mainboard context.
Change-Id: I1f097c8da722f3afab9aa1c80b96590c7ca457d5
Signed-off-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com>
---
src/device/root_device.c | 40 ++++------------------------------------
src/include/device/device.h | 2 --
2 files changed, 4 insertions(+), 38 deletions(-)
diff --git a/src/device/root_device.c b/src/device/root_device.c
index 49fa711..d0a3664 100644
--- a/src/device/root_device.c
+++ b/src/device/root_device.c
@@ -30,30 +30,6 @@
const char mainboard_name[] = CONFIG_MAINBOARD_VENDOR " " CONFIG_MAINBOARD_PART_NUMBER;
/**
- * Read the resources for the root device, that encompass the resources for
- * the entire system.
- *
- * @param root Pointer to the device structure for the system root device.
- */
-static void root_dev_read_resources(device_t root)
-{
- printk(BIOS_ERR, "%s should never be called.\n", __func__);
-}
-
-/**
- * Write the resources for every device.
- *
- * Write the resources for the root device, and every device under it which
- * are all of the devices.
- *
- * @param root Pointer to the device structure for the system root device.
- */
-static void root_dev_set_resources(device_t root)
-{
- printk(BIOS_ERR, "%s should never be called.\n", __func__);
-}
-
-/**
* Scan devices on static buses.
*
* The enumeration of certain buses is purely static. The existence of
@@ -121,10 +97,6 @@ unsigned int scan_static_bus(device_t bus, unsigned int max)
return max;
}
-static void root_dev_enable_resources(device_t dev)
-{
-}
-
/**
* Scan root bus for generic systems.
*
@@ -139,10 +111,6 @@ static unsigned int root_dev_scan_bus(device_t root, unsigned int max)
return scan_static_bus(root, max);
}
-static void root_dev_init(device_t root)
-{
-}
-
static void root_dev_reset(struct bus *bus)
{
printk(BIOS_INFO, "Resetting board...\n");
@@ -157,10 +125,10 @@ static void root_dev_reset(struct bus *bus)
* of a motherboard can override this if you want non-default behavior.
*/
struct device_operations default_dev_ops_root = {
- .read_resources = root_dev_read_resources,
- .set_resources = root_dev_set_resources,
- .enable_resources = root_dev_enable_resources,
- .init = root_dev_init,
+ .read_resources = DEVICE_NOOP,
+ .set_resources = DEVICE_NOOP,
+ .enable_resources = DEVICE_NOOP,
+ .init = DEVICE_NOOP,
.scan_bus = root_dev_scan_bus,
.reset_bus = root_dev_reset,
};
diff --git a/src/include/device/device.h b/src/include/device/device.h
index 30226bf..c1c9fdb 100644
--- a/src/include/device/device.h
+++ b/src/include/device/device.h
@@ -173,8 +173,6 @@ void dev_finalize_chips(void);
int reset_bus(struct bus *bus);
unsigned int scan_bus(struct device *bus, unsigned int _max);
void assign_resources(struct bus *bus);
-void enumerate_static_device(void);
-void enumerate_static_devices(void);
const char *dev_name(device_t dev);
const char *dev_path(device_t dev);
u32 dev_path_encode(device_t dev);
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 8251880cc6c001560539520eb558bd6e22615ad8
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 | 256 ++++++++++++++++++++++++++++++
3 files changed, 393 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..ded8fdc
--- /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_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..7965a7c
--- /dev/null
+++ b/src/soc/intel/fsp_baytrail/i2c.c
@@ -0,0 +1,256 @@
+/*
+ * 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 = (char*)base_adr[bus];
+ /* Ensure the desired device is valid */
+ if (bus > 6) {
+ printk(BIOS_ERR, "I2C: Only I2C controllers 0...6 are available.\n");
+ 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!\n", 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_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;
+}
Werner Zeh (werner.zeh(a)siemens.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8430
-gerrit
commit 3a14fddb5025713fc5130a93986d5760dcc5f108
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>
---
src/mainboard/siemens/Kconfig | 4 +
src/mainboard/siemens/mc_tcu3/Kconfig | 75 +++++++
src/mainboard/siemens/mc_tcu3/Makefile.inc | 51 +++++
src/mainboard/siemens/mc_tcu3/acpi/ec.asl | 0
src/mainboard/siemens/mc_tcu3/acpi/mainboard.asl | 25 +++
src/mainboard/siemens/mc_tcu3/acpi/superio.asl | 0
src/mainboard/siemens/mc_tcu3/acpi_tables.c | 254 +++++++++++++++++++++++
src/mainboard/siemens/mc_tcu3/board_info.txt | 4 +
src/mainboard/siemens/mc_tcu3/cmos.layout | 132 ++++++++++++
src/mainboard/siemens/mc_tcu3/devicetree.cb | 82 ++++++++
src/mainboard/siemens/mc_tcu3/dsdt.asl | 57 +++++
src/mainboard/siemens/mc_tcu3/fadt.c | 35 ++++
src/mainboard/siemens/mc_tcu3/gpio.c | 224 ++++++++++++++++++++
src/mainboard/siemens/mc_tcu3/hwinfo.hex | Bin 0 -> 997 bytes
src/mainboard/siemens/mc_tcu3/hwinfo10.hex | Bin 0 -> 485 bytes
src/mainboard/siemens/mc_tcu3/hwinfo12.hex | Bin 0 -> 485 bytes
src/mainboard/siemens/mc_tcu3/hwinfo15.hex | Bin 0 -> 485 bytes
src/mainboard/siemens/mc_tcu3/hwinfo19.hex | Bin 0 -> 485 bytes
src/mainboard/siemens/mc_tcu3/irqroute.c | 22 ++
src/mainboard/siemens/mc_tcu3/irqroute.h | 77 +++++++
src/mainboard/siemens/mc_tcu3/lcd_panel.c | 94 +++++++++
src/mainboard/siemens/mc_tcu3/lcd_panel.h | 39 ++++
src/mainboard/siemens/mc_tcu3/mainboard.c | 50 +++++
src/mainboard/siemens/mc_tcu3/modhwinfo.c | 150 +++++++++++++
src/mainboard/siemens/mc_tcu3/modhwinfo.h | 170 +++++++++++++++
src/mainboard/siemens/mc_tcu3/ptn3460.c | 181 ++++++++++++++++
src/mainboard/siemens/mc_tcu3/ptn3460.h | 78 +++++++
src/mainboard/siemens/mc_tcu3/romstage.c | 208 +++++++++++++++++++
src/mainboard/siemens/mc_tcu3/thermal.h | 33 +++
src/mainboard/siemens/mc_tcu3/version.hex | 3 +
30 files changed, 2048 insertions(+)
diff --git a/src/mainboard/siemens/Kconfig b/src/mainboard/siemens/Kconfig
index f03f822..e25cfa5 100644
--- a/src/mainboard/siemens/Kconfig
+++ b/src/mainboard/siemens/Kconfig
@@ -6,9 +6,13 @@ choice
config BOARD_SIEMENS_SITEMP_G1P1
bool "MB SITEMP-G1 (U1P0/U1P1)"
+config BOARD_SIEMENS_MC_TCU3
+ bool "MB TCU3"
+
endchoice
source "src/mainboard/siemens/sitemp_g1p1/Kconfig"
+source "src/mainboard/siemens/mc_tcu3/Kconfig"
config MAINBOARD_VENDOR
string
diff --git a/src/mainboard/siemens/mc_tcu3/Kconfig b/src/mainboard/siemens/mc_tcu3/Kconfig
new file mode 100644
index 0000000..2fa59ad
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/Kconfig
@@ -0,0 +1,75 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+##
+## 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
+##
+
+if BOARD_SIEMENS_MC_TCU3
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select SOC_INTEL_FSP_BAYTRAIL
+ select BOARD_ROMSIZE_KB_16384
+ select HAVE_ACPI_TABLES
+ select HAVE_OPTION_TABLE
+ select OVERRIDE_MRC_CACHE_LOC
+ select INCLUDE_MICROCODE_IN_BUILD
+ select ENABLE_BUILTIN_COM1
+ select HAVE_FSP_BIN if FSP_PACKAGE_DEFAULT
+ select ENABLE_FSP_FAST_BOOT
+ select TSC_MONOTONIC_TIMER
+ select DRIVER_INTEL_I210
+ select SOC_INTEL_FSP_BAYTRAIL_MD
+
+config MAINBOARD_DIR
+ string
+ default "siemens/mc_tcu3"
+
+config INCLUDE_ME
+ bool
+ default n
+
+config MAINBOARD_PART_NUMBER
+ string
+ default "MC_TCU3 (FSP)"
+
+
+config MAX_CPUS
+ int
+ default 16
+
+config CACHE_ROM_SIZE_OVERRIDE
+ hex
+ default 0x1000000
+
+config MRC_CACHE_LOC_OVERRIDE
+ hex
+ default 0xfff80000
+ depends on ENABLE_FSP_FAST_BOOT
+
+config CBFS_SIZE
+ hex
+ default 0x00e00000
+
+config FSP_PACKAGE_DEFAULT
+ bool "Configure defaults for the Intel FSP package"
+ default n
+
+config VGA_BIOS
+ bool
+ default y if FSP_PACKAGE_DEFAULT
+
+endif # BOARD_SIEMENS_MC_TCU3
diff --git a/src/mainboard/siemens/mc_tcu3/Makefile.inc b/src/mainboard/siemens/mc_tcu3/Makefile.inc
new file mode 100644
index 0000000..91d4bd2
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/Makefile.inc
@@ -0,0 +1,51 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2013 Google Inc.
+##
+## 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
+##
+
+romstage-y += modhwinfo.c
+
+ramstage-y += gpio.c
+ramstage-y += irqroute.c
+ramstage-y += modhwinfo.c
+ramstage-y += lcd_panel.c
+ramstage-y += ptn3460.c
+
+cbfs-files-y += hwinfo.hex
+hwinfo.hex-file := hwinfo.hex
+hwinfo.hex-type := 0x50
+hwinfo.hex-align := 0x1000
+
+cbfs-files-y += version.hex
+version.hex-file := version.hex
+version.hex-type := 0x50
+
+cbfs-files-y += hwinfo10.hex
+hwinfo10.hex-file := hwinfo10.hex
+hwinfo10.hex-type := 0x50
+
+cbfs-files-y += hwinfo12.hex
+hwinfo12.hex-file := hwinfo12.hex
+hwinfo12.hex-type := 0x50
+
+cbfs-files-y += hwinfo15.hex
+hwinfo15.hex-file := hwinfo15.hex
+hwinfo15.hex-type := 0x50
+
+cbfs-files-y += hwinfo19.hex
+hwinfo19.hex-file := hwinfo19.hex
+hwinfo19.hex-type := 0x50
diff --git a/src/mainboard/siemens/mc_tcu3/acpi/ec.asl b/src/mainboard/siemens/mc_tcu3/acpi/ec.asl
new file mode 100644
index 0000000..e69de29
diff --git a/src/mainboard/siemens/mc_tcu3/acpi/mainboard.asl b/src/mainboard/siemens/mc_tcu3/acpi/mainboard.asl
new file mode 100644
index 0000000..c1884c5
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/acpi/mainboard.asl
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Google Inc.
+ *
+ * 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
+ */
+
+Device (PWRB)
+{
+ Name(_HID, EisaId("PNP0C0C"))
+}
diff --git a/src/mainboard/siemens/mc_tcu3/acpi/superio.asl b/src/mainboard/siemens/mc_tcu3/acpi/superio.asl
new file mode 100644
index 0000000..e69de29
diff --git a/src/mainboard/siemens/mc_tcu3/acpi_tables.c b/src/mainboard/siemens/mc_tcu3/acpi_tables.c
new file mode 100644
index 0000000..5f81e26
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/acpi_tables.c
@@ -0,0 +1,254 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Google Inc.
+ * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 <types.h>
+#include <string.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <arch/acpi.h>
+#include <arch/ioapic.h>
+#include <arch/acpigen.h>
+#include <arch/smp/mpspec.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/msr.h>
+#include <baytrail/acpi.h>
+#include <baytrail/nvs.h>
+#include <baytrail/iomap.h>
+
+
+extern const unsigned char AmlCode[];
+
+static void acpi_create_gnvs(global_nvs_t *gnvs)
+{
+ acpi_init_gnvs(gnvs);
+
+ /* Enable USB ports in S3 */
+ gnvs->s3u0 = 1;
+ gnvs->s3u1 = 1;
+
+ /* Disable USB ports in S5 */
+ gnvs->s5u0 = 0;
+ gnvs->s5u1 = 0;
+
+ /* TPM Present */
+ gnvs->tpmp = 0;
+
+ /* Enable DPTF */
+ gnvs->dpte = 0;
+}
+
+unsigned long acpi_fill_madt(unsigned long current)
+{
+ /* Local APICs */
+ current = acpi_create_madt_lapics(current);
+
+ /* IOAPIC */
+ current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
+ 2, IO_APIC_ADDR, 0);
+
+ current = acpi_madt_irq_overrides(current);
+
+ return current;
+}
+
+unsigned long acpi_fill_ssdt_generator(unsigned long current,
+ const char *oem_table_id)
+{
+ generate_cpu_entries();
+ return (unsigned long) (acpigen_get_current());
+}
+
+unsigned long acpi_fill_slit(unsigned long current)
+{
+ // Not implemented
+ return current;
+}
+
+unsigned long acpi_fill_srat(unsigned long current)
+{
+ /* No NUMA, no SRAT */
+ return current;
+}
+
+#define ALIGN_CURRENT current = (ALIGN(current, 16))
+unsigned long write_acpi_tables(unsigned long start)
+{
+ unsigned long current;
+ int i;
+ acpi_rsdp_t *rsdp;
+ acpi_rsdt_t *rsdt;
+ acpi_xsdt_t *xsdt;
+ acpi_hpet_t *hpet;
+ acpi_madt_t *madt;
+ acpi_mcfg_t *mcfg;
+ acpi_fadt_t *fadt;
+ acpi_facs_t *facs;
+ acpi_header_t *ssdt;
+ acpi_header_t *ssdt2;
+ acpi_header_t *dsdt;
+ global_nvs_t *gnvs;
+
+ current = start;
+
+ /* Align ACPI tables to 16byte */
+ ALIGN_CURRENT;
+
+ printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx.\n", start);
+
+ /* We need at least an RSDP and an RSDT Table */
+ rsdp = (acpi_rsdp_t *) current;
+ current += sizeof(acpi_rsdp_t);
+ ALIGN_CURRENT;
+ rsdt = (acpi_rsdt_t *) current;
+ current += sizeof(acpi_rsdt_t);
+ ALIGN_CURRENT;
+ xsdt = (acpi_xsdt_t *) current;
+ current += sizeof(acpi_xsdt_t);
+ ALIGN_CURRENT;
+
+ /* clear all table memory */
+ memset((void *) start, 0, current - start);
+
+ acpi_write_rsdp(rsdp, rsdt, xsdt);
+ acpi_write_rsdt(rsdt);
+ acpi_write_xsdt(xsdt);
+
+ facs = (acpi_facs_t *) current;
+ current += sizeof(acpi_facs_t);
+ ALIGN_CURRENT;
+ acpi_create_facs(facs);
+ printk(BIOS_DEBUG, "ACPI: * FACS @ %p Length %x", facs,
+ facs->length);
+
+ dsdt = (acpi_header_t *) current;
+ memcpy(dsdt, &AmlCode, sizeof(acpi_header_t));
+ current += dsdt->length;
+ ALIGN_CURRENT;
+ memcpy(dsdt, &AmlCode, dsdt->length);
+ printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x", dsdt,
+ dsdt->length);
+
+ fadt = (acpi_fadt_t *) current;
+ current += sizeof(acpi_fadt_t);
+ ALIGN_CURRENT;
+ acpi_create_fadt(fadt, facs, dsdt);
+ acpi_add_table(rsdp, fadt);
+ printk(BIOS_DEBUG, "ACPI: * FADT @ %p Length %x", fadt,
+ fadt->header.length);
+
+ /*
+ * We explicitly add these tables later on:
+ */
+ hpet = (acpi_hpet_t *) current;
+ current += sizeof(acpi_hpet_t);
+ ALIGN_CURRENT;
+ acpi_create_intel_hpet(hpet);
+ acpi_add_table(rsdp, hpet);
+ printk(BIOS_DEBUG, "ACPI: * HPET @ %p Length %x\n", hpet,
+ hpet->header.length);
+
+ /* If we want to use HPET Timers Linux wants an MADT */
+ madt = (acpi_madt_t *) current;
+ acpi_create_madt(madt);
+ current += madt->header.length;
+ ALIGN_CURRENT;
+ acpi_add_table(rsdp, madt);
+ printk(BIOS_DEBUG, "ACPI: * MADT @ %p Length %x\n",madt,
+ madt->header.length);
+
+ mcfg = (acpi_mcfg_t *) current;
+ acpi_create_mcfg(mcfg);
+ current += mcfg->header.length;
+ ALIGN_CURRENT;
+ acpi_add_table(rsdp, mcfg);
+ printk(BIOS_DEBUG, "ACPI: * MCFG @ %p Length %x\n",mcfg,
+ mcfg->header.length);
+
+ /* Update GNVS pointer into CBMEM */
+ gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
+ if (!gnvs) {
+ printk(BIOS_DEBUG, "ACPI: Could not find CBMEM GNVS\n");
+ gnvs = (global_nvs_t *)current;
+ }
+
+ for (i=0; i < dsdt->length; i++) {
+ if (*(u32*)(((u32)dsdt) + i) == 0xC0DEBABE) {
+ printk(BIOS_DEBUG, "ACPI: Patching up global NVS in "
+ "DSDT at offset 0x%04x -> %p\n", i, gnvs);
+ *(u32*)(((u32)dsdt) + i) = (unsigned long)gnvs;
+ acpi_save_gnvs((unsigned long)gnvs);
+ break;
+ }
+ }
+
+ /* And fill it */
+ acpi_create_gnvs(gnvs);
+
+ /* And tell SMI about it */
+#if CONFIG_HAVE_SMI_HANDLER
+ smm_setup_structures(gnvs, NULL, NULL);
+#endif
+
+ current += sizeof(global_nvs_t);
+ ALIGN_CURRENT;
+
+ /* We patched up the DSDT, so we need to recalculate the checksum */
+ dsdt->checksum = 0;
+ dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length);
+
+ printk(BIOS_DEBUG, "ACPI Updated DSDT @ %p Length %x\n", dsdt,
+ dsdt->length);
+
+ ssdt = (acpi_header_t *)current;
+ memset(ssdt, 0, sizeof(acpi_header_t));
+ acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR);
+ if (ssdt->length) {
+ current += ssdt->length;
+ acpi_add_table(rsdp, ssdt);
+ printk(BIOS_DEBUG, "ACPI: * SSDT @ %p Length %x\n",ssdt,
+ ssdt->length);
+ ALIGN_CURRENT;
+ } else {
+ ssdt = NULL;
+ printk(BIOS_DEBUG, "ACPI: * SSDT not generated.\n");
+ }
+
+ ssdt2 = (acpi_header_t *)current;
+ memset(ssdt2, 0, sizeof(acpi_header_t));
+ acpi_create_serialio_ssdt(ssdt2);
+ if (ssdt2->length) {
+ current += ssdt2->length;
+ acpi_add_table(rsdp, ssdt2);
+ printk(BIOS_DEBUG, "ACPI: * SSDT2 @ %p Length %x\n",ssdt2,
+ ssdt2->length);
+ ALIGN_CURRENT;
+ } else {
+ ssdt2 = NULL;
+ printk(BIOS_DEBUG, "ACPI: * SSDT2 not generated.\n");
+ }
+
+ printk(BIOS_DEBUG, "current = %lx\n", current);
+
+ printk(BIOS_INFO, "ACPI: done.\n");
+ return current;
+}
diff --git a/src/mainboard/siemens/mc_tcu3/board_info.txt b/src/mainboard/siemens/mc_tcu3/board_info.txt
new file mode 100644
index 0000000..264dc3e
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/board_info.txt
@@ -0,0 +1,4 @@
+Board name: TCU3
+Category: misc
+ROM protocol: SPI
+ROM socketed: n
diff --git a/src/mainboard/siemens/mc_tcu3/cmos.layout b/src/mainboard/siemens/mc_tcu3/cmos.layout
new file mode 100644
index 0000000..115dcb5
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/cmos.layout
@@ -0,0 +1,132 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2007-2008 coresystems GmbH
+##
+## 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
+##
+
+# -----------------------------------------------------------------
+entries
+
+#start-bit length config config-ID name
+#0 8 r 0 seconds
+#8 8 r 0 alarm_seconds
+#16 8 r 0 minutes
+#24 8 r 0 alarm_minutes
+#32 8 r 0 hours
+#40 8 r 0 alarm_hours
+#48 8 r 0 day_of_week
+#56 8 r 0 day_of_month
+#64 8 r 0 month
+#72 8 r 0 year
+# -----------------------------------------------------------------
+# Status Register A
+#80 4 r 0 rate_select
+#84 3 r 0 REF_Clock
+#87 1 r 0 UIP
+# -----------------------------------------------------------------
+# Status Register B
+#88 1 r 0 auto_switch_DST
+#89 1 r 0 24_hour_mode
+#90 1 r 0 binary_values_enable
+#91 1 r 0 square-wave_out_enable
+#92 1 r 0 update_finished_enable
+#93 1 r 0 alarm_interrupt_enable
+#94 1 r 0 periodic_interrupt_enable
+#95 1 r 0 disable_clock_updates
+# -----------------------------------------------------------------
+# Status Register C
+#96 4 r 0 status_c_rsvd
+#100 1 r 0 uf_flag
+#101 1 r 0 af_flag
+#102 1 r 0 pf_flag
+#103 1 r 0 irqf_flag
+# -----------------------------------------------------------------
+# Status Register D
+#104 7 r 0 status_d_rsvd
+#111 1 r 0 valid_cmos_ram
+# -----------------------------------------------------------------
+# Diagnostic Status Register
+#112 8 r 0 diag_rsvd1
+
+# -----------------------------------------------------------------
+0 120 r 0 reserved_memory
+#120 264 r 0 unused
+
+# -----------------------------------------------------------------
+# RTC_BOOT_BYTE (coreboot hardcoded)
+384 1 e 4 boot_option
+385 1 e 4 last_boot
+388 4 r 0 reboot_bits
+#390 2 r 0 unused?
+
+# -----------------------------------------------------------------
+# coreboot config options: console
+392 3 e 5 baud_rate
+395 4 e 6 debug_level
+#399 1 r 0 unused
+
+# coreboot config options: cpu
+400 1 e 2 hyper_threading
+#401 7 r 0 unused
+
+# coreboot config options: southbridge
+408 1 e 1 nmi
+409 2 e 7 power_on_after_fail
+#411 5 r 0 unused
+
+# MRC Scrambler Seed values
+896 32 r 0 mrc_scrambler_seed
+928 32 r 0 mrc_scrambler_seed_s3
+
+# coreboot config options: check sums
+984 16 h 0 check_sum
+#1000 24 r 0 amd_reserved
+
+# -----------------------------------------------------------------
+
+enumerations
+
+#ID value text
+1 0 Disable
+1 1 Enable
+2 0 Enable
+2 1 Disable
+4 0 Fallback
+4 1 Normal
+5 0 115200
+5 1 57600
+5 2 38400
+5 3 19200
+5 4 9600
+5 5 4800
+5 6 2400
+5 7 1200
+6 1 Emergency
+6 2 Alert
+6 3 Critical
+6 4 Error
+6 5 Warning
+6 6 Notice
+6 7 Info
+6 8 Debug
+6 9 Spew
+7 0 Disable
+7 1 Enable
+7 2 Keep
+# -----------------------------------------------------------------
+checksums
+
+checksum 392 415 984
diff --git a/src/mainboard/siemens/mc_tcu3/devicetree.cb b/src/mainboard/siemens/mc_tcu3/devicetree.cb
new file mode 100644
index 0000000..c00c804
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/devicetree.cb
@@ -0,0 +1,82 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
+##
+## 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
+##
+
+chip soc/intel/fsp_baytrail
+
+ #### ACPI Register Settings ####
+ register "fadt_pm_profile" = "PM_MOBILE"
+ register "fadt_boot_arch" = "ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042"
+
+ #### FSP register settings ####
+ register "PcdSataMode" = "SATA_MODE_AHCI"
+ register "PcdMrcInitSPDAddr1" = "SPD_ADDR_DEFAULT"
+ register "PcdMrcInitSPDAddr2" = "SPD_ADDR_DEFAULT"
+ register "PcdMrcInitMmioSize" = "MMIO_SIZE_DEFAULT"
+ register "PcdeMMCBootMode" = "EMMC_FOLLOWS_DEVICETREE"
+ register "PcdIgdDvmt50PreAlloc" = "IGD_MEMSIZE_DEFAULT"
+ register "PcdApertureSize" = "APERTURE_SIZE_DEFAULT"
+ register "PcdGttSize" = "GTT_SIZE_DEFAULT"
+ register "PcdLpssSioEnablePciMode" = "LPSS_PCI_MODE_DEFAULT"
+ register "AzaliaAutoEnable" = "AZALIA_FOLLOWS_DEVICETREE"
+ register "LpeAcpiModeEnable" = "LPE_ACPI_MODE_DISABLED"
+
+ device cpu_cluster 0 on
+ device lapic 0 on end
+ end
+
+ device domain 0 on
+ device pci 00.0 on end # 8086 0F00 - SoC router
+ device pci 02.0 on end # 8086 0F31 - GFX
+ device pci 03.0 off end # 8086 0F38 - MIPI - camera interface
+
+ device pci 10.0 off end # 8086 0F14 - EMMC 4.1 Port (MMC1 pins) - (DO NOT USE) - Only 1 EMMC port at a time
+ device pci 11.0 on end # 8086 0F15 - SDIO Port (SD2 pins)
+ device pci 12.0 on end # 8086 0F16 - SD Port (SD3 pins)
+ device pci 13.0 on end # 8086 0F23 - SATA AHCI (0F20, 0F21, 0F22, 0F23)
+ device pci 14.0 on end # 8086 0F35 - USB XHCI - Only 1 USB controller at a time
+ device pci 15.0 off end # 8086 0F28 - LP Engine Audio
+ device pci 16.0 off end # 8086 0F37 - OTG controller
+ device pci 17.0 on end # 8086 0F50 - EMMC 4.5 Port (MMC1 pins) - Only 1 EMMC port at a time
+ device pci 18.0 on end # 8086 0F40 - SIO - DMA
+ device pci 18.1 on end # 8086 0F41 - I2C Port 1
+ device pci 18.2 on end # 8086 0F42 - I2C Port 2
+ device pci 18.3 on end # 8086 0F43 - I2C Port 3
+ device pci 18.4 on end # 8086 0F44 - I2C Port 4
+ device pci 18.5 on end # 8086 0F45 - I2C Port 5
+ device pci 18.6 on end # 8086 0F46 - I2C Port 6
+ device pci 18.7 on end # 8086 0F47 - I2C Port 7
+ device pci 1a.0 on end # 8086 0F18 - Trusted Execution Engine
+ device pci 1b.0 on end # 8086 0F04 - HD Audio
+ device pci 1c.0 on # 8086 0F48 - PCIe Root Port 1 (x4 slot)
+ device pci 0.0 on end # 8086 1538 - Intel i210 MACPHY
+ end
+ device pci 1c.1 on end # 8086 0F4A - PCIe Root Port 2 (half mini pcie slot)
+ device pci 1c.2 on end # 8086 0F4C - PCIe Root Port 3 (front x1 slot)
+ device pci 1c.3 on end # 8086 0F4E - PCIe Root Port 4 (rear x1 slot)
+ device pci 1d.0 off end # 8086 0F34 - USB EHCI - Only 1 USB controller at a time
+ device pci 1e.0 on end # 8086 0F06 - SIO - DMA
+ device pci 1e.1 on end # 8086 0F08 - PWM 1
+ device pci 1e.2 on end # 8086 0F09 - PWM 2
+ device pci 1e.3 on end # 8086 0F0A - HSUART 1
+ device pci 1e.4 on end # 8086 0F0C - HSUART 2
+ device pci 1e.5 on end # 8086 0F0E - SPI
+ device pci 1f.0 on end # 8086 0F1C - LPC bridge
+ device pci 1f.3 on end # 8086 0F12 - SMBus 0
+ end
+end
diff --git a/src/mainboard/siemens/mc_tcu3/dsdt.asl b/src/mainboard/siemens/mc_tcu3/dsdt.asl
new file mode 100644
index 0000000..cb2a4da
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/dsdt.asl
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2011 Google Inc.
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ *
+ * 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
+ */
+
+#define INCLUDE_LPE 1
+#define INCLUDE_SCC 1
+#define INCLUDE_EHCI 1
+#define INCLUDE_XHCI 1
+#define INCLUDE_LPSS 1
+
+
+DefinitionBlock(
+ "dsdt.aml",
+ "DSDT",
+ 0x02, // DSDT revision: ACPI v2.0
+ "COREv4", // OEM id
+ "COREBOOT", // OEM table id
+ 0x20110725 // OEM revision
+)
+{
+ // Some generic macros
+ #include <soc/intel/fsp_baytrail/acpi/platform.asl>
+
+ // global NVS and variables
+ #include <soc/intel/fsp_baytrail/acpi/globalnvs.asl>
+
+ #include <soc/intel/fsp_baytrail/acpi/cpu.asl>
+
+ Scope (\_SB) {
+ Device (PCI0)
+ {
+ #include <soc/intel/fsp_baytrail/acpi/southcluster.asl>
+ }
+ }
+
+ /* Chipset specific sleep states */
+ #include <soc/intel/fsp_baytrail/acpi/sleepstates.asl>
+
+ #include "acpi/mainboard.asl"
+}
diff --git a/src/mainboard/siemens/mc_tcu3/fadt.c b/src/mainboard/siemens/mc_tcu3/fadt.c
new file mode 100644
index 0000000..29d0c1d
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/fadt.c
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC.
+ *
+ * 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 <arch/acpi.h>
+#include <baytrail/acpi.h>
+
+void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt)
+{
+ acpi_header_t *header = &(fadt->header);
+
+ acpi_fill_in_fadt(fadt,facs,dsdt);
+
+ /* Platform specific customizations go here */
+
+ header->checksum = 0;
+ header->checksum =
+ acpi_checksum((void *) fadt, sizeof(acpi_fadt_t));
+}
diff --git a/src/mainboard/siemens/mc_tcu3/gpio.c b/src/mainboard/siemens/mc_tcu3/gpio.c
new file mode 100644
index 0000000..4306a23
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/gpio.c
@@ -0,0 +1,224 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2014 Sage Electronic Engineering, LLC.
+ *
+ * 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 <stdlib.h>
+#include <baytrail/gpio.h>
+#include "irqroute.h"
+
+/* NCORE GPIOs */
+static const struct soc_gpio_map gpncore_gpio_map[] = {
+ GPIO_FUNC2, /* GPIO 0 */
+ GPIO_FUNC2, /* GPIO 1 */
+ GPIO_FUNC2, /* GPIO 2 */
+ GPIO_FUNC2, /* GPIO 3 */
+ GPIO_FUNC2, /* GPIO 4 */
+ GPIO_FUNC2, /* GPIO 5 */
+ GPIO_FUNC2, /* GPIO 6 */
+ GPIO_FUNC2, /* GPIO 7 */
+ GPIO_FUNC2, /* GPIO 8 */
+ GPIO_FUNC2, /* GPIO 9 */
+ GPIO_FUNC2, /* GPIO 10 */
+ GPIO_FUNC2, /* GPIO 11 */
+ GPIO_FUNC2, /* GPIO 12 */
+ GPIO_FUNC2, /* GPIO 13 */
+ GPIO_FUNC2, /* GPIO 14 */
+ GPIO_FUNC2, /* GPIO 15 */
+ GPIO_FUNC2, /* GPIO 16 */
+ GPIO_FUNC2, /* GPIO 17 */
+ GPIO_FUNC2, /* GPIO 18 */
+ GPIO_FUNC2, /* GPIO 19 */
+ GPIO_FUNC2, /* GPIO 20 */
+ GPIO_FUNC2, /* GPIO 21 */
+ GPIO_FUNC2, /* GPIO 22 */
+ GPIO_FUNC2, /* GPIO 23 */
+ GPIO_FUNC2, /* GPIO 24 */
+ GPIO_FUNC2, /* GPIO 25 */
+ GPIO_FUNC2, /* GPIO 26 */
+ GPIO_END
+};
+
+/* SCORE GPIOs (GPIO_S0_SC_XX)*/
+static const struct soc_gpio_map gpscore_gpio_map[] = {
+ GPIO_FUNC1, /* GPIO_S0_SC[000] SATA_GP[0] .*/
+ GPIO_FUNC2, /* GPIO_S0_SC[001] SATA_GP[1] SATA_DEVSLP[0] .*/
+ GPIO_FUNC1, /* GPIO_S0_SC[002] SATA_LED# */
+ GPIO_FUNC1, /* GPIO_S0_SC[003] PCIE_CLKREQ[0]# */
+ GPIO_FUNC1, /* GPIO_S0_SC[004] PCIE_CLKREQ[1]# */
+ GPIO_FUNC1, /* GPIO_S0_SC[005] PCIE_CLKREQ[2]# */
+ GPIO_FUNC1, /* GPIO_S0_SC[006] PCIE_CLKREQ[3]# */
+ GPIO_NC, /* GPIO_S0_SC[007] RESERVED SD3_WP */
+ GPIO_FUNC2, /* GPIO_S0_SC[008] I2S0_CLK HDA_RST# */
+ GPIO_FUNC2, /* GPIO_S0_SC[009] I2S0_FRM HDA_SYNC */
+ GPIO_FUNC2, /* GPIO_S0_SC[010] I2S0_DATAOUT HDA_CLK */
+ GPIO_FUNC2, /* GPIO_S0_SC[011] I2S0_DATAIN HDA_SDO */
+ GPIO_FUNC2, /* GPIO_S0_SC[012] I2S1_CLK HDA_SDI[0] */
+ GPIO_NC, /* GPIO_S0_SC[013] I2S1_FRM HDA_SDI[1] */
+ GPIO_DEFAULT, /* GPIO_S0_SC[014] I2S1_DATAOUT RESERVED */
+ GPIO_DEFAULT, /* GPIO_S0_SC[015] I2S1_DATAIN RESERVED */
+ GPIO_NC, /* GPIO_S0_SC[016] MMC1_CLK MMC1_45_CLK */
+ GPIO_NC, /* GPIO_S0_SC[017] MMC1_D[0] MMC1_45_D[0] */
+ GPIO_NC, /* GPIO_S0_SC[018] MMC1_D[1] MMC1_45_D[1] */
+ GPIO_NC, /* GPIO_S0_SC[019] MMC1_D[2] MMC1_45_D[2] */
+ GPIO_NC, /* GPIO_S0_SC[020] MMC1_D[3] MMC1_45_D[3] */
+ GPIO_NC, /* GPIO_S0_SC[021] MMC1_D[4] MMC1_45_D[4] */
+ GPIO_NC, /* GPIO_S0_SC[022] MMC1_D[5] MMC1_45_D[5] */
+ GPIO_NC, /* GPIO_S0_SC[023] MMC1_D[6] MMC1_45_D[6] */
+ GPIO_NC, /* GPIO_S0_SC[024] MMC1_D[7] MMC1_45_D[7] */
+ GPIO_NC, /* GPIO_S0_SC[025] MMC1_CMD MMC1_45_CMD */
+ GPIO_NC, /* GPIO_S0_SC[026] MMC1_RST# SATA_DEVSLP[0] MMC1_45_RST# */
+ GPIO_FUNC1, /* GPIO_S0_SC[027] SD2_CLK */
+ GPIO_FUNC1, /* GPIO_S0_SC[028] SD2_D[0] */
+ GPIO_FUNC1, /* GPIO_S0_SC[029] SD2_D[1] */
+ GPIO_FUNC1, /* GPIO_S0_SC[030] SD2_D[2] */
+ GPIO_FUNC1, /* GPIO_S0_SC[031] SD2_D[3]_CD# */
+ GPIO_FUNC1, /* GPIO_S0_SC[032] SD2_CMD */
+ GPIO_NC, /* GPIO_S0_SC[033] SD3_CLK */
+ GPIO_NC, /* GPIO_S0_SC[034] SD3_D[0] */
+ GPIO_NC, /* GPIO_S0_SC[035] SD3_D[1] */
+ GPIO_NC, /* GPIO_S0_SC[036] SD3_D[2] */
+ GPIO_NC, /* GPIO_S0_SC[037] SD3_D[3] */
+ GPIO_NC, /* GPIO_S0_SC[038] SD3_CD# */
+ GPIO_NC, /* GPIO_S0_SC[039] SD3_CMD */
+ GPIO_NC, /* GPIO_S0_SC[040] SD3_1P8EN */
+ GPIO_NC, /* GPIO_S0_SC[041] SD3_PWREN# */
+ GPIO_FUNC1, /* GPIO_S0_SC[042] ILB_LPC_AD[0] */
+ GPIO_FUNC1, /* GPIO_S0_SC[043] ILB_LPC_AD[1] */
+ GPIO_FUNC1, /* GPIO_S0_SC[044] ILB_LPC_AD[2] */
+ GPIO_FUNC1, /* GPIO_S0_SC[045] ILB_LPC_AD[3] */
+ GPIO_FUNC1, /* GPIO_S0_SC[046] ILB_LPC_FRAME# */
+ GPIO_FUNC1, /* GPIO_S0_SC[047] ILB_LPC_CLK[0] */
+ GPIO_FUNC1, /* GPIO_S0_SC[048] ILB_LPC_CLK[1] */
+ GPIO_FUNC1, /* GPIO_S0_SC[049] ILB_LPC_CLKRUN# */
+ GPIO_FUNC1, /* GPIO_S0_SC[050] ILB_LPC_SERIRQ */
+ GPIO_FUNC1, /* GPIO_S0_SC[051] PCU_SMB_DATA */
+ GPIO_FUNC1, /* GPIO_S0_SC[052] PCU_SMB_CLK */
+ GPIO_FUNC1, /* GPIO_S0_SC[053] PCU_SMB_ALERT# */
+ GPIO_FUNC1, /* GPIO_S0_SC[054] ILB_8254_SPKR RESERVED */
+ GPIO_OUT_HIGH, /* GPIO_S0_SC[055] RESERVED */
+ GPIO_FUNC0, /* GPIO_S0_SC[056] RESERVED */
+ GPIO_FUNC1, /* GPIO_S0_SC[057] PCU_UART_TXD */
+ GPIO_OUT_LOW, /* GPIO_S0_SC[058] RESERVED */
+ GPIO_OUT_LOW, /* GPIO_S0_SC[059] RESERVED */
+ GPIO_OUT_LOW, /* GPIO_S0_SC[060] RESERVED */
+ GPIO_FUNC1, /* GPIO_S0_SC[061] PCU_UART_RXD */
+ GPIO_FUNC1, /* GPIO_S0_SC[062] LPE_I2S2_CLK SATA_DEVSLP[1] RESERVED */
+ GPIO_FUNC1, /* GPIO_S0_SC[063] LPE_I2S2_FRM RESERVED */
+ GPIO_FUNC1, /* GPIO_S0_SC[064] LPE_I2S2_DATAIN */
+ GPIO_FUNC1, /* GPIO_S0_SC[065] LPE_I2S2_DATAOUT */
+ GPIO_FUNC1, /* GPIO_S0_SC[066] SIO_SPI_CS# */
+ GPIO_FUNC1, /* GPIO_S0_SC[067] SIO_SPI_MISO */
+ GPIO_FUNC1, /* GPIO_S0_SC[068] SIO_SPI_MOSI */
+ GPIO_FUNC1, /* GPIO_S0_SC[069] SIO_SPI_CLK */
+ GPIO_FUNC1, /* GPIO_S0_SC[070] SIO_UART1_RXD RESERVED */
+ GPIO_FUNC1, /* GPIO_S0_SC[071] SIO_UART1_TXD RESERVED */
+ GPIO_FUNC1, /* GPIO_S0_SC[072] SIO_UART1_RTS# */
+ GPIO_FUNC1, /* GPIO_S0_SC[073] SIO_UART1_CTS# */
+ GPIO_FUNC1, /* GPIO_S0_SC[074] SIO_UART2_RXD */
+ GPIO_FUNC1, /* GPIO_S0_SC[075] SIO_UART2_TXD */
+ GPIO_FUNC1, /* GPIO_S0_SC[076] SIO_UART2_RTS# */
+ GPIO_FUNC1, /* GPIO_S0_SC[077] SIO_UART2_CTS# */
+ GPIO_FUNC1, /* GPIO_S0_SC[078] SIO_I2C0_DATA */
+ GPIO_FUNC1, /* GPIO_S0_SC[079] SIO_I2C0_CLK */
+ GPIO_FUNC1, /* GPIO_S0_SC[080] SIO_I2C1_DATA */
+ GPIO_FUNC1, /* GPIO_S0_SC[081] SIO_I2C1_CLK RESERVED */
+ GPIO_FUNC1, /* GPIO_S0_SC[082] SIO_I2C2_DATA */
+ GPIO_FUNC1, /* GPIO_S0_SC[083] SIO_I2C2_CLK */
+ GPIO_FUNC1, /* GPIO_S0_SC[084] SIO_I2C3_DATA */
+ GPIO_FUNC1, /* GPIO_S0_SC[085] SIO_I2C3_CLK */
+ GPIO_FUNC1, /* GPIO_S0_SC[086] SIO_I2C4_DATA */
+ GPIO_FUNC1, /* GPIO_S0_SC[087] SIO_I2C4_CLK */
+ GPIO_FUNC1, /* GPIO_S0_SC[088] SIO_I2C5_DATA */
+ GPIO_FUNC1, /* GPIO_S0_SC[089] SIO_I2C5_CLK */
+ GPIO_FUNC1, /* GPIO_S0_SC[090] SIO_I2C6_DATA ILB_NMI */
+ GPIO_FUNC1, /* GPIO_S0_SC[091] SIO_I2C6_CLK SD3_WP */
+ GPIO_FUNC1, /* RESERVED GPIO_S0_SC[092] */
+ GPIO_FUNC1, /* RESERVED GPIO_S0_SC[093] */
+ GPIO_FUNC1, /* GPIO_S0_SC[094] SIO_PWM[0] */
+ GPIO_FUNC1, /* GPIO_S0_SC[095] SIO_PWM[1] */
+ GPIO_FUNC1, /* GPIO_S0_SC[096] PMC_PLT_CLK[0] */
+ GPIO_FUNC1, /* GPIO_S0_SC[097] PMC_PLT_CLK[1] */
+ GPIO_FUNC1, /* GPIO_S0_SC[098] PMC_PLT_CLK[2] */
+ GPIO_FUNC1, /* GPIO_S0_SC[099] PMC_PLT_CLK[3] */
+ GPIO_FUNC1, /* GPIO_S0_SC[100] PMC_PLT_CLK[4] */
+ GPIO_DEFAULT, /* GPIO_S0_SC[101] PMC_PLT_CLK[5] */
+ GPIO_END
+};
+
+/* SSUS GPIOs (GPIO_S5) */
+static const struct soc_gpio_map gpssus_gpio_map[] = {
+ GPIO_INPUT_PD_10K, /* GPIO_S5[00] RESERVED */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[01] RESERVED RESERVED RESERVED PMC_WAKE_PCIE[1]# */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[02] RESERVED RESERVED RESERVED PMC_WAKE_PCIE[2]# */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[03] RESERVED RESERVED RESERVED PMC_WAKE_PCIE[3]# */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[04] RESERVED RESERVED RESERVED RESERVED */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[05] PMC_SUSCLK[1] RESERVED RESERVED RESERVED */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[06] PMC_SUSCLK[2] RESERVED RESERVED RESERVED */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[07] PMC_SUSCLK[3] RESERVED RESERVED RESERVED */
+ GPIO_INPUT_PU_10K, /* GPIO_S5[08] RESERVED RESERVED RESERVED RESERVED */
+ GPIO_INPUT_PU_10K, /* GPIO_S5[09] RESERVED RESERVED ESERVED RESERVED */
+ GPIO_INPUT_PU_10K, /* GPIO_S5[10] RESERVED RESERVED RESERVED */
+ GPIO_DEFAULT, /* PMC_SUSPWRDNACK GPIO_S5[11] - - */
+ GPIO_DEFAULT, /* PMC_SUSCLK[0] GPIO_S5[12] - - */
+ GPIO_DEFAULT, /* RESERVED GPIO_S5[13] - - */
+ GPIO_DEFAULT, /* RESERVED GPIO_S5[14] USB_ULPI_RST# - */
+ GPIO_DEFAULT, /* PMC_WAKE_PCIE[0]# GPIO_S5[15] - - */
+ GPIO_DEFAULT, /* PMC_PWRBTN# GPIO_S5[16] - - */
+ GPIO_DEFAULT, /* RESERVED GPIO_S5[17] - - */
+ GPIO_DEFAULT, /* PMC_SUS_STAT# GPIO_S5[18] - - */
+ GPIO_DEFAULT, /* USB_OC[0]# GPIO_S5[19] - - */
+ GPIO_DEFAULT, /* USB_OC[1]# GPIO_S5[20] - - */
+ GPIO_DEFAULT, /* PCU_SPI_CS[1]# GPIO_S5[21] - */
+ GPIO_DEFAULT, /* GPIO_S5[22] RESERVED RESERVED RESERVED RESERVED */
+ GPIO_DEFAULT, /* GPIO_S5[23] RESERVED RESERVED RESERVED RESERVED */
+ GPIO_DEFAULT, /* GPIO_S5[24] RESERVED RESERVED RESERVED RESERVED */
+ GPIO_DEFAULT, /* GPIO_S5[25] RESERVED RESERVED RESERVED RESERVED */
+ GPIO_DEFAULT, /* GPIO_S5[26] RESERVED RESERVED RESERVED RESERVED */
+ GPIO_DEFAULT, /* GPIO_S5[27] RESERVED RESERVED ESERVED RESERVED */
+ GPIO_DEFAULT, /* GPIO_S5[28] RESERVED RESERVED RESERVED RESERVED */
+ GPIO_DEFAULT, /* GPIO_S5[29] RESERVED RESERVED RESERVED RESERVED */
+ GPIO_DEFAULT, /* GPIO_S5[30] RESERVED RESERVED RESERVED RESERVED */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[31] USB_ULPI_CLK RESERVED RESERVED */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[32] USB_ULPI_DATA[0] RESERVED RESERVED */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[33] USB_ULPI_DATA[1] RESERVED RESERVED */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[34] USB_ULPI_DATA[2] RESERVED RESERVED */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[35] USB_ULPI_DATA[3] RESERVED RESERVED */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[36] USB_ULPI_DATA[4] RESERVED RESERVED */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[37] USB_ULPI_DATA[5] RESERVED RESERVED */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[38] USB_ULPI_DATA[6] RESERVED RESERVED */
+ GPIO_INPUT_PD_10K, /* GPIO_S5[39] USB_ULPI_DATA[7] RESERVED RESERVED */
+ GPIO_INPUT_PD_20K, /* GPIO_S5[40] USB_ULPI_DIR RESERVED RESERVED */
+ GPIO_INPUT_PD_20K, /* GPIO_S5[41] USB_ULPI_NXT RESERVED RESERVED */
+ GPIO_INPUT_PD_20K, /* GPIO_S5[42] USB_ULPI_STP RESERVED RESERVED */
+ GPIO_INPUT_PD_20K, /* GPIO_S5[43] USB_ULPI_REFCLK RESERVED RESERVED */
+ GPIO_END
+};
+
+static struct soc_gpio_config gpio_config = {
+ .ncore = gpncore_gpio_map,
+ .score = gpscore_gpio_map,
+ .ssus = gpssus_gpio_map,
+ .core_dirq = NULL,
+ .sus_dirq = NULL,
+};
+
+struct soc_gpio_config* mainboard_get_gpios(void)
+{
+ return &gpio_config;
+}
diff --git a/src/mainboard/siemens/mc_tcu3/hwinfo.hex b/src/mainboard/siemens/mc_tcu3/hwinfo.hex
new file mode 100644
index 0000000..ce7fc07
Binary files /dev/null and b/src/mainboard/siemens/mc_tcu3/hwinfo.hex differ
diff --git a/src/mainboard/siemens/mc_tcu3/hwinfo10.hex b/src/mainboard/siemens/mc_tcu3/hwinfo10.hex
new file mode 100644
index 0000000..390c6b4
Binary files /dev/null and b/src/mainboard/siemens/mc_tcu3/hwinfo10.hex differ
diff --git a/src/mainboard/siemens/mc_tcu3/hwinfo12.hex b/src/mainboard/siemens/mc_tcu3/hwinfo12.hex
new file mode 100644
index 0000000..471af4f
Binary files /dev/null and b/src/mainboard/siemens/mc_tcu3/hwinfo12.hex differ
diff --git a/src/mainboard/siemens/mc_tcu3/hwinfo15.hex b/src/mainboard/siemens/mc_tcu3/hwinfo15.hex
new file mode 100644
index 0000000..4cbbe5b
Binary files /dev/null and b/src/mainboard/siemens/mc_tcu3/hwinfo15.hex differ
diff --git a/src/mainboard/siemens/mc_tcu3/hwinfo19.hex b/src/mainboard/siemens/mc_tcu3/hwinfo19.hex
new file mode 100644
index 0000000..f8510fc
Binary files /dev/null and b/src/mainboard/siemens/mc_tcu3/hwinfo19.hex differ
diff --git a/src/mainboard/siemens/mc_tcu3/irqroute.c b/src/mainboard/siemens/mc_tcu3/irqroute.c
new file mode 100644
index 0000000..552be8f
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/irqroute.c
@@ -0,0 +1,22 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ *
+ * 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 "irqroute.h"
+
+DEFINE_IRQ_ROUTES;
diff --git a/src/mainboard/siemens/mc_tcu3/irqroute.h b/src/mainboard/siemens/mc_tcu3/irqroute.h
new file mode 100644
index 0000000..08552c5
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/irqroute.h
@@ -0,0 +1,77 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ *
+ * 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 IRQROUTE_H
+#define IRQROUTE_H
+
+#include <soc/intel/fsp_baytrail/baytrail/irq.h>
+#include <soc/intel/fsp_baytrail/baytrail/pci_devs.h>
+
+/*
+ *IR02h GFX INT(A) - PIRQ A
+ *IR10h EMMC INT(ABCD) - PIRQ DEFG
+ *IR11h SDIO INT(A) - PIRQ B
+ *IR12h SD INT(A) - PIRQ C
+ *IR13h SATA INT(A) - PIRQ D
+ *IR14h XHCI INT(A) - PIRQ E
+ *IR15h LP Audio INT(A) - PIRQ F
+ *IR17h MMC INT(A) - PIRQ F
+ *IR18h SIO INT(ABCD) - PIRQ BADC
+ *IR1Ah TXE INT(A) - PIRQ F
+ *IR1Bh HD Audio INT(A) - PIRQ G
+ *IR1Ch PCIe INT(ABCD) - PIRQ EFGH
+ *IR1Dh EHCI INT(A) - PIRQ D
+ *IR1Eh SIO INT(ABCD) - PIRQ BDEF
+ *IR1Fh LPC INT(ABCD) - PIRQ HGBC
+ */
+#define PCI_DEV_PIRQ_ROUTES \
+ PCI_DEV_PIRQ_ROUTE(GFX_DEV, A, A, A, A), \
+ PCI_DEV_PIRQ_ROUTE(EMMC_DEV, D, E, F, G), \
+ PCI_DEV_PIRQ_ROUTE(SDIO_DEV, B, A, A, A), \
+ PCI_DEV_PIRQ_ROUTE(SD_DEV, C, A, A, A), \
+ PCI_DEV_PIRQ_ROUTE(SATA_DEV, D, A, A, A), \
+ PCI_DEV_PIRQ_ROUTE(XHCI_DEV, E, A, A, A), \
+ PCI_DEV_PIRQ_ROUTE(LPE_DEV, F, A, A, A), \
+ PCI_DEV_PIRQ_ROUTE(MMC45_DEV, F, A, A, A), \
+ PCI_DEV_PIRQ_ROUTE(SIO1_DEV, B, A, D, C), \
+ PCI_DEV_PIRQ_ROUTE(TXE_DEV, F, A, A, A), \
+ PCI_DEV_PIRQ_ROUTE(HDA_DEV, G, A, A, A), \
+ PCI_DEV_PIRQ_ROUTE(PCIE_DEV, E, F, G, H), \
+ PCI_DEV_PIRQ_ROUTE(EHCI_DEV, D, A, A, A), \
+ PCI_DEV_PIRQ_ROUTE(SIO2_DEV, B, D, E, F), \
+ PCI_DEV_PIRQ_ROUTE(PCU_DEV, H, G, B, C)
+
+/*
+ * Route each PIRQ[A-H] to a PIC IRQ[0-15]
+ * Reserved: 0, 1, 2, 8, 13
+ * PS2 keyboard: 12
+ * ACPI/SCI: 9
+ * Floppy: 6
+ */
+#define PIRQ_PIC_ROUTES \
+ PIRQ_PIC(A, 4), \
+ PIRQ_PIC(B, 5), \
+ PIRQ_PIC(C, 7), \
+ PIRQ_PIC(D, 10), \
+ PIRQ_PIC(E, 11), \
+ PIRQ_PIC(F, 12), \
+ PIRQ_PIC(G, 14), \
+ PIRQ_PIC(H, 15)
+
+#endif /* IRQROUTE_H */
diff --git a/src/mainboard/siemens/mc_tcu3/lcd_panel.c b/src/mainboard/siemens/mc_tcu3/lcd_panel.c
new file mode 100644
index 0000000..1dc429e
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/lcd_panel.c
@@ -0,0 +1,94 @@
+/*
+ * 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 <cbfs.h>
+#include <console/console.h>
+#include <string.h>
+#include "modhwinfo.h"
+#include "baytrail/gpio.h"
+#include "lcd_panel.h"
+#include "ptn3460.h"
+
+/** \brief Reads GPIOs used for LCD panel encoding and returns the 4 bit value
+ * @param no parameters
+ * @return LCD panel type encoded in 4 bits
+ */
+u8 get_lcd_panel_type(void)
+{
+ u8 lcd_type_gpio;
+
+ lcd_type_gpio = ((read_ssus_gpio(LCD_TYPE_GPIO_BIT3) << 3) |
+ (read_ssus_gpio(LCD_TYPE_GPIO_BIT2) << 2) |
+ (read_ssus_gpio(LCD_TYPE_GPIO_BIT1) << 1) |
+ (read_ssus_gpio(LCD_TYPE_GPIO_BIT0)));
+ /* There is an inverter in this signals so we need to invert them as well */
+ return ((~lcd_type_gpio) & 0x0f);
+}
+
+/** \brief Setup LCD panel
+ * @param no parameters
+ * @return 0 on success otherwise error value
+ */
+int setup_lcd_panel(void)
+{
+ u8 lcd_type;
+ int status;
+ struct edidinfo *eib = NULL;
+ struct shortinfo *sib = NULL;
+ char blockname[33];
+
+ lcd_type = get_lcd_panel_type();
+ printk(BIOS_INFO, "LCD: Found panel type %d\n", lcd_type);
+ switch (lcd_type) {
+ case LCD_PANEL_TYPE_10_INCH:
+ strcpy(blockname, "hwinfo10.hex");
+ break;
+ case LCD_PANEL_TYPE_12_INCH:
+ strcpy(blockname, "hwinfo12.hex");
+ break;
+ case LCD_PANEL_TYPE_15_INCH:
+ strcpy(blockname, "hwinfo15.hex");
+ break;
+ case LCD_PANEL_TYPE_19_INCH:
+ strcpy(blockname, "hwinfo19.hex");
+ break;
+ case LCD_PANEL_TYPE_EDID:
+ strcpy(blockname, "hwinfo.hex");
+ break;
+ default:
+ printk(BIOS_ERR, "LCD: No supported panel found.\n");
+ status = 1;
+ break;
+ }
+
+ /* Now that we have the panel type, get the matching block and setup */
+ /* the DP2LVDS converter accordingly */
+ eib = get_edidinfo(blockname);
+ sib = get_shortinfo(blockname);
+
+ if ((!eib) || (!sib)) {
+ printk(BIOS_ERR, "LCD: Info block named \"%s\" not found!\n", blockname);
+ status = 1;
+ } else {
+ printk(BIOS_INFO, "LCD: Found SIB at 0x%x, EIB at 0x%x\n",
+ (int)sib, (int)eib);
+ status = ptn3460_init(lcd_type, eib, sib);
+ printk(BIOS_INFO, "LCD: Setup PTN with status 0x%x\n", status);
+ }
+ return status;
+}
diff --git a/src/mainboard/siemens/mc_tcu3/lcd_panel.h b/src/mainboard/siemens/mc_tcu3/lcd_panel.h
new file mode 100644
index 0000000..b423dc0
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/lcd_panel.h
@@ -0,0 +1,39 @@
+/*
+ * 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 _LCD_PANEL_H_
+#define _LCD_PANEL_H_
+
+/* This GPIOs are used for LCD panel type encoding */
+#define LCD_TYPE_GPIO_BIT0 40
+#define LCD_TYPE_GPIO_BIT1 41
+#define LCD_TYPE_GPIO_BIT2 42
+#define LCD_TYPE_GPIO_BIT3 43
+
+#define LCD_PANEL_TYPE_10_INCH 4
+#define LCD_PANEL_TYPE_12_INCH 7
+#define LCD_PANEL_TYPE_15_INCH 6
+#define LCD_PANEL_TYPE_19_INCH 1
+#define LCD_PANEL_TYPE_EDID 15
+
+u8 get_lcd_panel_type(void);
+int setup_lcd_panel(void);
+
+
+#endif /* _LCD_PANEL_H_ */
diff --git a/src/mainboard/siemens/mc_tcu3/mainboard.c b/src/mainboard/siemens/mc_tcu3/mainboard.c
new file mode 100644
index 0000000..fb350e5
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/mainboard.c
@@ -0,0 +1,50 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved.
+ *
+ * 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 <types.h>
+#include <string.h>
+#include <device/device.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <device/pci_ops.h>
+#include <console/console.h>
+#if CONFIG_VGA_ROM_RUN
+#include <x86emu/x86emu.h>
+#endif
+#include <pc80/mc146818rtc.h>
+#include <arch/acpi.h>
+#include <arch/io.h>
+#include <arch/interrupt.h>
+#include <boot/coreboot_tables.h>
+
+#include "lcd_panel.h"
+
+/*
+ * mainboard_enable is executed as first thing after enumerate_buses().
+ * This is the earliest point to add customization.
+ */
+static void mainboard_enable(device_t dev)
+{
+ setup_lcd_panel();
+}
+
+struct chip_operations mainboard_ops = {
+ .enable_dev = mainboard_enable,
+};
diff --git a/src/mainboard/siemens/mc_tcu3/modhwinfo.c b/src/mainboard/siemens/mc_tcu3/modhwinfo.c
new file mode 100644
index 0000000..95bb76c
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/modhwinfo.c
@@ -0,0 +1,150 @@
+/*
+ * 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 "modhwinfo.h"
+#include "lcd_panel.h"
+#include <cbfs.h>
+#include <string.h>
+
+/** \brief This function will find the first linked info block.
+ * @param *filename Filename in cbfs
+ * @param *file_offset Pointer to the offset of the cbfs file contents
+ * @return u8* Pointer to the found block
+ */
+u8* get_first_linked_block(char *filename, u8 **file_offset)
+{
+ u8* block_ptr = NULL;
+
+ block_ptr = (cbfs_get_file_content(CBFS_DEFAULT_MEDIA, filename,
+ 0x50, NULL));
+ if (!block_ptr)
+ return NULL;
+ if (!strncmp((char*)block_ptr, "H1W2M3I4", LEN_MAGIC_NUM)) {
+ if ((*((u16*)(block_ptr + HWI_LEN_OFFSET)) == LEN_MAIN_HWINFO) &&
+ (*((s32*)(block_ptr + NEXT_OFFSET_HWINFO)) != 0x00)) {
+ *file_offset = block_ptr;
+ return *((s32*)(block_ptr + NEXT_OFFSET_HWINFO)) + block_ptr;
+ } else
+ return NULL;
+ } else if (!strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM)) {
+ *file_offset = block_ptr;
+ return block_ptr;
+ } else
+ return NULL;
+}
+
+/** \brief This function will find the main info block
+ * @param *filename Filename in cbfs
+ * @return *hwinfo Pointer to the data of the main info block
+ */
+struct hwinfo* get_hwinfo(char *filename)
+{
+ struct hwinfo* main_hwinfo;
+
+ main_hwinfo = (struct hwinfo*)(cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
+ filename, 0x50, NULL));
+ if ((main_hwinfo) &&
+ (!strncmp(main_hwinfo->magicNumber, "H1W2M3I4", LEN_MAGIC_NUM)) &&
+ (main_hwinfo->length == LEN_MAIN_HWINFO))
+ return main_hwinfo;
+ else
+ return NULL;
+}
+
+/** \brief This function will find the short info block
+ * @param *filename Filename in cbfs
+ * @return *shortinfo Pointer to the data of the short info block
+ */
+struct shortinfo* get_shortinfo(char *filename)
+{
+ u8 *block_ptr = NULL;
+ u8 *file_offset = NULL;
+
+ block_ptr = get_first_linked_block(filename, &file_offset);
+ if ((block_ptr == NULL) ||
+ (strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM)))
+ return NULL;
+
+ if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_SHORT_INFO)
+ return (struct shortinfo *)block_ptr;
+
+ block_ptr = (file_offset + *((s32*)(block_ptr + NEXT_OFFSET_EDID)));
+ if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_SHORT_INFO)
+ return (struct shortinfo *)block_ptr;
+ else
+ return NULL;
+}
+
+/** \brief This function will find the edid info block
+ * @param *filename Filename in cbfs
+ * @return *edidinfo Pointer to the data of the edid info block
+ */
+struct edidinfo* get_edidinfo(char *filename)
+{
+ u8 *block_ptr = NULL;
+ u8 *file_offset = NULL;
+
+ block_ptr = get_first_linked_block(filename, &file_offset);
+ if ((block_ptr == NULL) ||
+ (strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM)))
+ return NULL;
+
+ if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_EDID_INFO)
+ return (struct edidinfo *)block_ptr;
+
+ block_ptr = (file_offset + *((s32*)(block_ptr + NEXT_OFFSET_SIB)));
+ if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_EDID_INFO)
+ return (struct edidinfo *)block_ptr;
+ else
+ return NULL;
+}
+
+/** \brief This function will search for a MAC address which can be assigned
+ * to a MACPHY.
+ * @param pci_bdf Bus, device and function of the given PCI-device
+ * @param mac buffer where to store the MAC address
+ * @return cb_err CB_ERR or CB_SUCCESS
+ */
+enum cb_err mainboard_get_mac_address(u16 bus, u8 devfn, u8 mac[6])
+{
+ struct hwinfo* main_hwinfo;
+ u32 i;
+
+ main_hwinfo = get_hwinfo((char*)"hwinfo.hex");
+ if (!main_hwinfo)
+ return CB_ERR;
+ /* Ensure the first MAC-Address is not completely 0x00 or 0xff */
+ for (i = 0; i < 6; i++) {
+ if (main_hwinfo->macAddress1[i] != 0xFF)
+ break;
+ }
+ if (i == 6){
+ return CB_ERR;
+ }
+ for (i = 0; i < 6; i++) {
+ if (main_hwinfo->macAddress1[i] != 0x00)
+ break;
+ }
+ if (i == 6){
+ return CB_ERR;
+ } else {
+ memcpy(mac, main_hwinfo->macAddress1, 6);
+ return CB_SUCCESS;
+ }
+}
diff --git a/src/mainboard/siemens/mc_tcu3/modhwinfo.h b/src/mainboard/siemens/mc_tcu3/modhwinfo.h
new file mode 100644
index 0000000..6eb8f05
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/modhwinfo.h
@@ -0,0 +1,170 @@
+/*
+ * 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 _MODHWINFO_H_
+#define _MODHWINFO_H_
+
+#include <types.h>
+
+#define LEN_MAGIC_NUM 8
+#define LEN_MLFB 20
+#define LEN_SERIAL_NUM 16
+#define LEN_HW_REVISION 2
+#define LEN_MAC_ADDRESS 6
+#define LEN_SPD 128
+#define NUMBER_OF_MAC_ADDR 4
+#define LEN_EDID 128
+#define LEN_MAIN_HWINFO 509
+#define LEN_SHORT_INFO 289
+#define LEN_EDID_INFO 181
+#define NEXT_OFFSET_HWINFO 476
+#define NEXT_OFFSET_SIB 260
+#define NEXT_OFFSET_EDID 176
+#define HWI_LEN_OFFSET 12
+
+/* Define some masks and values */
+#define SIB_HWINIT_IDX 0x0e
+#define SIB_COLOR_6BIT 0x00
+#define SIB_COLOR_8BIT 0x01
+#define SIB_COLOR_10BIT 0x02
+#define SIB_DISP_CON_IDX 0x16
+#define SIB_LVDS_SINGLE_LANE 0x00
+#define SIB_LVDS_DUAL_LANE 0x05
+
+struct PhysDevStruc {
+ u8 bustype;
+ u8 devfn;
+ u16 bus;
+} __attribute__ ((packed));
+
+
+struct hwinfo {
+// Offset 0x0
+ char magicNumber[LEN_MAGIC_NUM];
+// Offset 0x08
+ u8 versionID[4];
+// Offset 0x0c
+ u16 length;
+// Offset 0x0e
+ char BGR_Name[128];
+//Offset 0x8e
+ char MLFB[LEN_MLFB];
+// Offset 0xa2
+ u8 uniqueNumber[16];
+// Offset 0xb2
+ u8 fill_1[12];
+// Offset 0xbe
+ u8 hwRevision[LEN_HW_REVISION];
+//Offset 0xc0
+ u8 macAddress1[LEN_MAC_ADDRESS];
+ u8 numOfAuxMacAddr1;
+ u8 fill_2;
+//Offset 0xc8
+ u8 macAddress2[LEN_MAC_ADDRESS];
+ u8 numOfAuxMacAddr2;
+ u8 fill_3;
+//Offset 0xd0
+ u8 macAddress3[LEN_MAC_ADDRESS];
+ u8 numOfAuxMacAddr3;
+ u8 fill_4;
+//Offset 0xd8
+ u8 macAddress4[LEN_MAC_ADDRESS];
+ u8 numOfAuxMacAddr4;
+ u8 fill_5;
+// Offset 0xe0
+ u8 SPD[LEN_SPD];
+// Offset 0x160
+ u8 fill_6[88];
+// Offset 0x1b8
+ u32 featureFlags;
+// Offset 0x1bc
+ u8 fill_7[4];
+// Offset 0x1c0
+ u32 biosFlags;
+// Offset 0x1c4
+ u8 fill_8[8];
+//Offset 0x1cc
+ struct PhysDevStruc etherDev[NUMBER_OF_MAC_ADDR];
+// Offset 0x1dc
+ s32 nextInfoOffset;
+// Offset 0x1e0
+ u8 fill_9[4];
+// Offset 0x1e4
+ u32 portRTC;
+// Offset 0x1e8
+ u8 typeRTC;
+// Offset 0x1e9
+ u8 fill_10[20];
+} __attribute__ ((packed));
+
+struct shortinfo {
+// Offset 0x0
+ char magicNumber[LEN_MAGIC_NUM];
+// Offset 0x08
+ u8 versionID[4];
+// Offset 0x0c
+ u16 length;
+// Offset 0x0e
+ char BGR_Name[128];
+//Offset 0x8e
+ char MLFB[LEN_MLFB];
+// Offset 0xa2
+ u8 uniqueNumber[26];
+// Offset 0xbc
+ u8 fill_1[12];
+//Offset 0xc8
+ u8 hwRevision[2];
+// Offset 0xca
+ u8 fill_2[18];
+// Offset 0xdc
+ u8 panelFeatures[32];
+// Offset 0xfc
+ u8 fill_3[8];
+// Offset 0x104
+ s32 nextInfoOffset;
+// Offset 0x108
+ u8 fill_4[25];
+} __attribute__ ((packed));
+
+struct edidinfo {
+// Offset 0x0
+ char magicNumber[LEN_MAGIC_NUM];
+// Offset 0x08
+ u8 versionID[4];
+// Offset 0x0c
+ u16 length;
+// Offset 0x0e
+ u8 fill_1[2];
+// Offset 0x10
+ u8 edid[LEN_EDID];
+// Offset 0x90
+ u8 fill_2[32];
+// Offset 0xb0
+ s32 nextInfoOffset;
+// Offset 0xb4
+ u8 fill_3;
+} __attribute__ ((packed));
+
+u8* get_first_linked_block(char *filename, u8 **starting_adr);
+struct hwinfo* get_hwinfo(char *filename);
+struct shortinfo* get_shortinfo(char *filename);
+struct edidinfo* get_edidinfo(char *filename);
+enum cb_err mainboard_get_mac_address(u16 bus, u8 devfn, u8 mac[6]);
+
+#endif /* _MODHWINFO_H_ */
diff --git a/src/mainboard/siemens/mc_tcu3/ptn3460.c b/src/mainboard/siemens/mc_tcu3/ptn3460.c
new file mode 100644
index 0000000..bb204e5
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/ptn3460.c
@@ -0,0 +1,181 @@
+/*
+ * 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 <console/console.h>
+#include "baytrail/i2c.h"
+#include "ptn3460.h"
+
+/** \brief This functions sets up the DP2LVDS-converter to be used with the
+ * appropriate lcd panel
+ * @param lcd_type Type of LCD we should set up the converter for
+ * @param *sib Pointer to short info block structure
+ * @param *eib Pointer to EDID info block structure
+ * @return 0 on success or error code
+ */
+int ptn3460_init(char lcd_type, struct edidinfo *eib, struct shortinfo *sib)
+{
+ struct ptn_3460_config cfg;
+ int status;
+
+
+ status = i2c_init(PTN_I2C_CONTROLER);
+ if (status)
+ return (PTN_BUS_ERROR | status);
+
+ /* If we are here, we have all the desired information for setting up */
+ /* DP2LVDS converter. In addition, the information matches the connected */
+ /* LCD-panel and therefore, we do not have to distinguish between */
+ /* different panels here for the timing. Inside the converter, table 6 */
+ /* will be used for the timings. */
+ status = ptn3460_write_edid(6, eib->edid);
+ if (status)
+ return status;
+ /* Select this table to be emulated */
+ ptn_select_edid(6);
+ /* Read PTN configuration data */
+ status = i2c_read(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF,
+ (u8*)&cfg, PTN_CONFIG_LEN);
+ if (status)
+ return (PTN_BUS_ERROR | status);
+
+ /* Set up configuration data according to the information blocks we get */
+ cfg.dp_interface_ctrl = 0;
+ cfg.lvds_interface_ctrl1 = 0x00;
+ if (sib->panelFeatures[SIB_DISP_CON_IDX] == SIB_LVDS_DUAL_LANE)
+ cfg.lvds_interface_ctrl1 |= 0x0b; /* Turn on dual LVDS lane and clock */
+ if ((sib->panelFeatures[SIB_HWINIT_IDX] & 0x03) == SIB_COLOR_6BIT)
+ cfg.lvds_interface_ctrl1 |= 0x20; /* Use 18 bits per pixel */
+
+ cfg.lvds_interface_ctrl2 = 0x03; /* no clock spreading, 300 mV LVDS swing */
+ cfg.lvds_interface_ctrl3 = 0x00; /* no LVDS signal swap */
+ cfg.t2_delay = 1; /* Delay T2 (VDD to LVDS active) by 16 ms */
+ cfg.t3_timing = 5; /* 250 ms from LVDS to backlight active */
+ cfg.t12_timing = 20; /* 1 second re-power delay */
+ cfg.t4_timing = 3; /* 150 ms backlight off to LVDS inactive */
+ cfg.t5_delay = 1; /* Delay T5 (LVDS to VDD inactive) by 16 ms */
+ cfg.backlight_ctrl = 0; /* Enable backlight control */
+
+ /* Write back configuration data to PTN3460 */
+ status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF,
+ (u8*)&cfg, PTN_CONFIG_LEN);
+ if (status)
+ return (PTN_BUS_ERROR | status);
+ else
+ return PTN_NO_ERROR;
+}
+
+/** \brief This functions reads one desired EDID data structure from PTN3460
+ * @param edid_num Number of EDID that must be read (0..6)
+ * @param *data Pointer to a buffer where to store read data
+ * @return 0 on success or error code
+ */
+int ptn3460_read_edid(u8 edid_num, u8 *data)
+{
+ int status;
+
+ if (edid_num > PTN_MAX_EDID_NUM)
+ return PTN_INVALID_EDID;
+ /* First enable access to the desired EDID table */
+ status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF + 5,
+ &edid_num, 1);
+ if (status)
+ return (PTN_BUS_ERROR | status);
+
+ /* Now we can simply read back EDID-data */
+ status = i2c_read(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_EDID_OFF,
+ data, PTN_EDID_LEN);
+ if (status)
+ return (PTN_BUS_ERROR | status);
+ else
+ return PTN_NO_ERROR;
+}
+
+/** \brief This functions writes one EDID data structure to PTN3460
+ * @param edid_num Number of EDID that must be written (0..6)
+ * @param *data Pointer to a buffer where data to write is stored in
+ * @return 0 on success or error code
+ */
+int ptn3460_write_edid(u8 edid_num, u8 *data)
+{
+ int status;
+
+ if (edid_num > PTN_MAX_EDID_NUM)
+ return PTN_INVALID_EDID;
+ /* First enable access to the desired EDID table */
+ status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF + 5,
+ &edid_num, 1);
+ if (status)
+ return (PTN_BUS_ERROR | status);
+
+ /* Now we can simply write EDID-data to ptn3460 */
+ status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_EDID_OFF,
+ data, PTN_EDID_LEN);
+ if (status)
+ return (PTN_BUS_ERROR | status);
+ else
+ return PTN_NO_ERROR;
+}
+
+/** \brief This functions selects one of 7 EDID-tables inside PTN3460
+ * which should be emulated on display port and turn emulation ON
+ * @param edid_num Number of EDID to emulate (0..6)
+ * @return 0 on success or error code
+ */
+int ptn_select_edid (u8 edid_num)
+{
+ int status;
+ u8 val;
+
+ if (edid_num > PTN_MAX_EDID_NUM)
+ return PTN_INVALID_EDID;
+ /* Enable emulation of the desired EDID table */
+ val = (edid_num << 1) | 1;
+ status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_CONFIG_OFF + 4,
+ &val, 1);
+ if (status)
+ return (PTN_BUS_ERROR | status);
+ else
+ return PTN_NO_ERROR;
+}
+
+/** \brief This functions performs a flash operation which will write
+ * current configuration table (all the EDID-tables and the
+ * configuration space with a total amount of 1 KByte)
+ * to the internal flash of PTN3460
+ * @param none
+ * @return 0 on success or error code
+ */
+int ptn3460_flash_config(void)
+{
+ int status;
+ struct ptn_3460_flash flash;
+
+ flash.cmd = 0x01; /* perform erase and flash cycle */
+ flash.magic = 0x7845; /* Magic number to protect flash operation */
+ flash.trigger = 0x56; /* This value starts flash operation */
+ status = i2c_write(PTN_I2C_CONTROLER, PTN_SLAVE_ADR, PTN_FLASH_CFG_OFF,
+ (u8*)&flash, PTN_FLASH_CFG_LEN);
+ if (status) {
+ return (PTN_BUS_ERROR | status);
+ } else {
+ /* To ensure the flash operation is finished, we have to wait 300 ms */
+ mdelay(300);
+ return PTN_NO_ERROR;
+ }
+}
diff --git a/src/mainboard/siemens/mc_tcu3/ptn3460.h b/src/mainboard/siemens/mc_tcu3/ptn3460.h
new file mode 100644
index 0000000..b975a69
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/ptn3460.h
@@ -0,0 +1,78 @@
+/*
+ * 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 PTN3460_H_
+#define PTN3460_H_
+
+#include <delay.h>
+#include "modhwinfo.h"
+#include "lcd_panel.h"
+
+#define PTN_SLAVE_ADR 0x20
+#define PTN_I2C_CONTROLER 0
+
+#define PTN_EDID_OFF 0x00
+#define PTN_EDID_LEN 0x80
+#define PTN_CONFIG_OFF 0x80
+#define PTN_CONFIG_LEN 0x19
+#define PTN_FLASH_CFG_OFF 0xE8
+#define PTN_FLASH_CFG_LEN 0x04
+#define PTN_MAX_EDID_NUM 6
+
+/* Define some error codes that can be used */
+#define PTN_NO_ERROR 0x00000000
+#define PTN_BUS_ERROR 0x10000000
+#define PTN_INVALID_EDID 0x20000000
+
+struct ptn_3460_config{
+ u8 dp_interface_ctrl; /* DiplayPort interface control */
+ u8 lvds_interface_ctrl1; /* LVDS interface control register 1 */
+ u8 lvds_interface_ctrl2; /* LVDS interface control register 2 */
+ u8 lvds_interface_ctrl3; /* LVDS interface control register 3 */
+ u8 edid_rom_emulation; /* select which EDID-block is emulated */
+ u8 edid_rom_access_ctrl; /* select which EDID block to map to 0..0x7F */
+ u8 pwm_min[3]; /* smallest PWM frequency for back light */
+ u8 pwm_max[3]; /* biggest PWM frequency for back light */
+ u8 fast_link_ctrl; /* Fast link training control register */
+ u8 pin_cfg_ctrl1; /* Pin configuration control register 1 */
+ u8 pin_cfg_ctrl2; /* Pin configuration control register 2 */
+ u8 pwm_default; /* Default PWM bit count in DPCD register */
+ u16 pwm_value; /* Current PWM bit count in DPCD register */
+ u8 pwm_default_freq; /* Default PWM frequency in DPCD register */
+ u8 t3_timing; /* Panel T3 timing value */
+ u8 t12_timing; /* Panel T12 timing value */
+ u8 backlight_ctrl; /* Back light control register */
+ u8 t2_delay; /* Panel T2 delay */
+ u8 t4_timing; /* Panel T4 timing value */
+ u8 t5_delay; /* Panel T5 delay */
+}__attribute__((packed));
+
+struct ptn_3460_flash{
+ u8 cmd; /* Flash command (erase or erase and flash) */
+ u16 magic; /* Magic number needed by the flash algorithm */
+ u8 trigger; /* Trigger for starting flash operation */
+}__attribute__((packed));
+
+
+int ptn3460_init(char lcd_type, struct edidinfo *eib, struct shortinfo *sib);
+int ptn3460_read_edid(u8 edid_num, u8 *data);
+int ptn3460_write_edid(u8 edid_num, u8 *data);
+int ptn_select_edid(u8 edid_num);
+int ptn3460_flash_config(void);
+#endif /* PTN3460_H_ */
diff --git a/src/mainboard/siemens/mc_tcu3/romstage.c b/src/mainboard/siemens/mc_tcu3/romstage.c
new file mode 100644
index 0000000..5274529
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/romstage.c
@@ -0,0 +1,208 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2013 Google Inc.
+ * Copyright (C) 2013 Sage Electronic Engineering, LLC.
+ *
+ * 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 <stddef.h>
+#include <arch/cpu.h>
+#include <lib.h>
+#include <arch/io.h>
+#include <arch/cbfs.h>
+#include <arch/stages.h>
+#include <console/console.h>
+#include <cbmem.h>
+#include <cpu/x86/mtrr.h>
+#include <romstage_handoff.h>
+#include <timestamp.h>
+#include <baytrail/gpio.h>
+#include <baytrail/iomap.h>
+#include <baytrail/lpc.h>
+#include <baytrail/pci_devs.h>
+#include <baytrail/romstage.h>
+#include <baytrail/acpi.h>
+#include <baytrail/baytrail.h>
+#include <drivers/intel/fsp/fsp_util.h>
+#include "modhwinfo.h"
+
+/**
+ * /brief mainboard call for setup that needs to be done before fsp init
+ *
+ */
+void early_mainboard_romstage_entry()
+{
+
+}
+
+/**
+ * Get function disables - most of these will be done automatically
+ * @param fd_mask
+ * @param fd2_mask
+ */
+void get_func_disables(uint32_t *fd_mask, uint32_t *fd2_mask)
+{
+
+}
+
+/**
+ * /brief mainboard call for setup that needs to be done after fsp init
+ *
+ */
+void late_mainboard_romstage_entry()
+{
+
+}
+
+const uint32_t mAzaliaVerbTableData13[] = {
+/*
+ *ALC262 Verb Table - 10EC0262
+ */
+ /* Pin Complex (NID 0x11 ) */
+ 0x01171CF0,
+ 0x01171D11,
+ 0x01171E11,
+ 0x01171F41,
+ /* Pin Complex (NID 0x12 ) */
+ 0x01271CF0,
+ 0x01271D11,
+ 0x01271E11,
+ 0x01271F41,
+ /* Pin Complex (NID 0x14 ) */
+ 0x01471C10,
+ 0x01471D40,
+ 0x01471E01,
+ 0x01471F01,
+ /* Pin Complex (NID 0x15 ) */
+ 0x01571CF0,
+ 0x01571D11,
+ 0x01571E11,
+ 0x01571F41,
+ /* Pin Complex (NID 0x16 ) */
+ 0x01671CF0,
+ 0x01671D11,
+ 0x01671E11,
+ 0x01671F41,
+ /* Pin Complex (NID 0x18 ) */
+ 0x01871C20,
+ 0x01871D98,
+ 0x01871EA1,
+ 0x01871F01,
+ /* Pin Complex (NID 0x19 ) */
+ 0x01971C21,
+ 0x01971D98,
+ 0x01971EA1,
+ 0x01971F02,
+ /* Pin Complex (NID 0x1A ) */
+ 0x01A71C2F,
+ 0x01A71D30,
+ 0x01A71E81,
+ 0x01A71F01,
+ /* Pin Complex (NID 0x1B ) */
+ 0x01B71C1F,
+ 0x01B71D40,
+ 0x01B71E21,
+ 0x01B71F02,
+ /* Pin Complex (NID 0x1C ) */
+ 0x01C71CF0,
+ 0x01C71D11,
+ 0x01C71E11,
+ 0x01C71F41,
+ /* Pin Complex (NID 0x1D ) */
+ 0x01D71C01,
+ 0x01D71DC6,
+ 0x01D71E14,
+ 0x01D71F40,
+ /* Pin Complex (NID 0x1E ) */
+ 0x01E71CF0,
+ 0x01E71D11,
+ 0x01E71E11,
+ 0x01E71F41,
+ /* Pin Complex (NID 0x1F ) */
+ 0x01F71CF0,
+ 0x01F71D11,
+ 0x01F71E11,
+ 0x01F71F41 };
+
+const PCH_AZALIA_VERB_TABLE mAzaliaVerbTable[] = { {
+/*
+ * VerbTable: (RealTek ALC262)
+ * Revision ID = 0xFF, support all steps
+ * Codec Verb Table For AZALIA
+ * Codec Address: CAd value (0/1/2)
+ * Codec Vendor: 0x10EC0262
+ */
+ {
+ 0x10EC0262, /* Vendor ID/Device IDA */
+ 0x0000, /* SubSystem ID */
+ 0xFF, /* Revision IDA */
+ 0x01, /* Front panel support (1=yes, 2=no) */
+ 0x000B, /* Number of Rear Jacks = 11 */
+ 0x0002 /* Number of Front Jacks = 2 */
+ },
+ (uint32_t *)mAzaliaVerbTableData13 } };
+
+const PCH_AZALIA_CONFIG mainboard_AzaliaConfig = {
+ .Pme = 1,
+ .DS = 1,
+ .DA = 0,
+ .HdmiCodec = 1,
+ .AzaliaVCi = 1,
+ .Rsvdbits = 0,
+ .AzaliaVerbTableNum = 1,
+ .AzaliaVerbTable = (PCH_AZALIA_VERB_TABLE *)mAzaliaVerbTable,
+ .ResetWaitTimer = 300 };
+
+/** /brief customize fsp parameters here if needed
+ */
+void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer)
+{
+ struct hwinfo *hwi_main;
+ UPD_DATA_REGION *UpdData = FspRtBuffer->Common.UpdDataRgnPtr;
+
+ /* Initialize the Azalia Verb Tables to mainboard specific version */
+ UpdData->AzaliaConfigPtr = (UINT32)&mainboard_AzaliaConfig;
+
+ /* Disable 2nd DIMM on Bakersport*/
+#if IS_ENABLED(BOARD_INTEL_BAKERSPORT_FSP)
+ UpdData->PcdMrcInitSPDAddr2 = 0x00; /* cannot use SPD_ADDR_DISABLED at this point */
+#endif
+ /* Get SPD data from hardware information block and setup memory down */
+ /* parameters for FSP accordingly */
+ hwi_main = get_hwinfo((char*)"hwinfo.hex");
+ if (hwi_main) {
+ UpdData->PcdMemoryParameters.EnableMemoryDown = 1;
+ UpdData->PcdMemoryParameters.DRAMType = hwi_main->SPD[2];
+ UpdData->PcdMemoryParameters.DIMM0Enable = hwi_main->SPD[3] & 0x01;
+ UpdData->PcdMemoryParameters.DIMM1Enable = (hwi_main->SPD[3] >> 1) & 0x01;
+ UpdData->PcdMemoryParameters.DIMMDensity = hwi_main->SPD[4];
+ UpdData->PcdMemoryParameters.DIMMDWidth = hwi_main->SPD[5];
+ UpdData->PcdMemoryParameters.DIMMSides = hwi_main->SPD[7];
+ UpdData->PcdMemoryParameters.DIMMBusWidth = hwi_main->SPD[8];
+ UpdData->PcdMemoryParameters.DRAMSpeed = hwi_main->SPD[12];
+ UpdData->PcdMemoryParameters.DIMMtCL = hwi_main->SPD[14];
+ UpdData->PcdMemoryParameters.DIMMtWR = hwi_main->SPD[17];
+ UpdData->PcdMemoryParameters.DIMMtRPtRCD = hwi_main->SPD[18];
+ UpdData->PcdMemoryParameters.DIMMtRRD = hwi_main->SPD[19];
+ UpdData->PcdMemoryParameters.DIMMtWTR = hwi_main->SPD[26];
+ UpdData->PcdMemoryParameters.DIMMtRTP = hwi_main->SPD[27];
+ UpdData->PcdMemoryParameters.DIMMtFAW = hwi_main->SPD[28];
+ /*If one need output from MRC to be used in Intel RMT, simply */
+ /*enable the following line */
+ //UpdData->PcdMrcDebugMsg = 1;
+ } else
+ printk(BIOS_ERR, "HWInfo not found, leave default timings for DDR3.\n");
+}
diff --git a/src/mainboard/siemens/mc_tcu3/thermal.h b/src/mainboard/siemens/mc_tcu3/thermal.h
new file mode 100644
index 0000000..78dfcbe
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/thermal.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The Chromium OS Authors. All rights reserved.
+ *
+ * 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 MAINBOARD_THERMAL_H
+#define MAINBOARD_THERMAL_H
+
+
+/* Temperature which OS will shutdown at */
+#define CRITICAL_TEMPERATURE 100
+
+/* Temperature which OS will throttle CPU */
+#define PASSIVE_TEMPERATURE 90
+
+/* Tj_max value for calculating PECI CPU temperature */
+#define MAX_TEMPERATURE 100
+
+#endif /* MAINBOARD_THERMAL_H */
diff --git a/src/mainboard/siemens/mc_tcu3/version.hex b/src/mainboard/siemens/mc_tcu3/version.hex
new file mode 100644
index 0000000..10b9c23
--- /dev/null
+++ b/src/mainboard/siemens/mc_tcu3/version.hex
@@ -0,0 +1,3 @@
+$USRV01.00.00.00
+$PLTTCU30.3
+$EXVV01.00.00.00
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 e1b89141a9e8798d6d9d0d535b6338913a1ec98b
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>
---
src/soc/intel/fsp_baytrail/Kconfig | 4 ++++
.../intel/fsp_baytrail/microcode/microcode_blob.c | 20 ++++++++++++--------
.../intel/fsp_baytrail/microcode/microcode_size.h | 6 +++++-
3 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/src/soc/intel/fsp_baytrail/Kconfig b/src/soc/intel/fsp_baytrail/Kconfig
index 87839c4..d97879f 100644
--- a/src/soc/intel/fsp_baytrail/Kconfig
+++ b/src/soc/intel/fsp_baytrail/Kconfig
@@ -50,6 +50,10 @@ config CPU_SPECIFIC_OPTIONS
select SUPPORT_CPU_UCODE_IN_CBFS
select ROMSTAGE_RTC_INIT
+config SOC_INTEL_FSP_BAYTRAIL_MD
+ bool
+ default n
+
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 57aae34..ec63327 100644
--- a/src/soc/intel/fsp_baytrail/microcode/microcode_blob.c
+++ b/src/soc/intel/fsp_baytrail/microcode/microcode_blob.c
@@ -19,20 +19,24 @@
unsigned microcode[] = {
-/*
+ /*
* The problem is that these microcode files are not in the tree. They come
* with FSP, so let the user deal with the include paths when HAVE_FSP_BIN
* is enabled.
*/
#if IS_ENABLED(CONFIG_HAVE_FSP_BIN)
+#if !IS_ENABLED(CONFIG_SOC_INTEL_FSP_BAYTRAIL_MD)
+ /* Region size is 0x30000 - update in microcode_size.h if it gets larger. */
+ #include "M0230672228.h" // M0230672: Bay Trail "Super SKU" B0/B1
+ #include "M0130673322.h" // M0130673: Bay Trail I B2 / B3
+ #include "M0130679901.h" // M0130679: Bay Trail I D0
+#else
+ /* Region size is 0x10000 - update in microcode_size.h if it gets larger. */
+ #include "M0C30678829.h" // M0C30678: Bay Trail M D Stepping
+#endif /* CONFIG_SOC_INTEL_FSP_BAYTRAIL_MD */
+#endif /* CONFIG_HAVE_FSP_BIN */
-/* 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
-
-#endif
- /* Dummy terminator */
+ /* Dummy terminator */
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
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..2af2201 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_MD)
+ #define MICROCODE_REGION_LENGTH 0x30000
+#else
+ #define MICROCODE_REGION_LENGTH 0x10000
+#endif