the following patch was just integrated into master:
commit 5b0420a87b913d7c672fa8cd7b21218b6de3a247
Author: David Hubbard <david.c.hubbard+coreboot(a)gmail.com>
Date: Tue May 28 16:33:15 2013 -0600
crossgcc/buildgcc: Remove unneeded 'break' statements
Bash case statements are terminated with ';;'.
Unlike C, bash case statements will not continue to the next case. No 'break' is needed.
Change-Id: I62e7e91f3223ac4052728a1ca12a4681af0dc036
Signed-off-by: David Hubbard <david.c.hubbard+coreboot(a)gmail.com>
Reviewed-on: http://review.coreboot.org/3330
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer(a)coreboot.org>
See http://review.coreboot.org/3330 for details.
-gerrit
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/144
-gerrit
commit 961dc13c671289f5f46475da859400155365ffc6
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Tue May 21 12:35:08 2013 -0500
early_smbus: Add early SMBus implementation for VIA chipsets
Add a common implementation of SMBus functionality for early chipsets. Note
however, that existing via chipsets are not ported to this code. Porting
will require hardware testing to make sure everything is fine.
This code is used in the VIA VX900 branch.
Change-Id: If5ad8cd0942ac02d358a0139967e7d85d395660f
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/southbridge/via/common/early_smbus.c | 176 +++++++++++++++++++++++++++++++
1 file changed, 176 insertions(+)
diff --git a/src/southbridge/via/common/early_smbus.c b/src/southbridge/via/common/early_smbus.c
new file mode 100644
index 0000000..262d641
--- /dev/null
+++ b/src/southbridge/via/common/early_smbus.c
@@ -0,0 +1,176 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011-2013 Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
+ *
+ * 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file via_early_sambus.c
+ *
+ * This file defines the implementations for the functions defined in
+ * device/early/smbus.h
+ *
+ * These implementations work with most via chipsets. Any VIA port should try
+ * to use these. Makefile.inc needs to be adapted to link against this file
+ * during romstage:
+ * @code
+ * romstage-y += ./../../../southbridge/via/common/early_smbus.c
+ * @endcode
+ *
+ * These functions are marked weak in the event that one or more might need to
+ * be overridden. This may be the case when, for example, a chipset needs a
+ * longer delay for a specific operation.
+ */
+
+#include <device/early_smbus.h>
+
+#include <arch/io.h>
+
+/**
+ * \brief SMBus IO ports in relation to the base IO port
+ */
+#define SMBHSTSTAT(base) (u16)(u32)base + 0x0
+#define SMBSLVSTAT(base) (u16)(u32)base + 0x1
+#define SMBHSTCTL(base) (u16)(u32)base + 0x2
+#define SMBHSTCMD(base) (u16)(u32)base + 0x3
+#define SMBXMITADD(base) (u16)(u32)base + 0x4
+#define SMBHSTDAT0(base) (u16)(u32)base + 0x5
+#define SMBHSTDAT1(base) (u16)(u32)base + 0x6
+#define SMBBLKDAT(base) (u16)(u32)base + 0x7
+#define SMBSLVCTL(base) (u16)(u32)base + 0x8
+#define SMBTRNSADD(base) (u16)(u32)base + 0x9
+#define SMBSLVDATA (base) (u16)(u32)base + 0xa
+
+#define SMBUS_TIMEOUT (100*1000*10)
+
+/**
+ * \brief Brief delay for SMBus transactions
+ */
+void smbus_delay(void)
+{
+ inb(0x80);
+}
+
+/**
+ * \brief Clear the SMBus host status register
+ *
+ * @param smbus_dev The base SMBus IO port
+ */
+__attribute__ ((weak))
+void smbus_reset(u32 smbus_dev)
+{
+ outb(0xdf, SMBHSTSTAT(smbus_dev));
+}
+
+/**
+ * \brief Print an error, should it occur. If no error, just exit.
+ *
+ * @param smbus_dev The base SMBus IO port
+ * @param host_status The data returned on the host status register after
+ * a transaction is processed.
+ * @param loops The number of times a transaction was attempted.
+ * @return 0 if no error occurred
+ * 1 if an error was detected
+ */
+__attribute__ ((weak))
+int smbus_print_error(u32 smbus_dev, u8 host_status, int loops)
+{
+ /* Check if there actually was an error. */
+ if ((host_status == 0x00 || host_status == 0x40 ||
+ host_status == 0x42) && (loops < SMBUS_TIMEOUT))
+ return 0;
+
+ if (loops >= SMBUS_TIMEOUT)
+ printsmbus("SMBus timeout\n");
+ if (host_status & (1 << 4))
+ printsmbus("Interrupt/SMI# was Failed Bus Transaction\n");
+ if (host_status & (1 << 3))
+ printsmbus("Bus error\n");
+ if (host_status & (1 << 2))
+ printsmbus("Device error\n");
+ if (host_status & (1 << 1))
+ printsmbus("Interrupt/SMI# completed successfully\n");
+ if (host_status & (1 << 0))
+ printsmbus("Host busy\n");
+ return 1;
+}
+
+/**
+ * \brief Checks if the SMBus is currently busy with a transaction
+ *
+ * @param smbus_dev The base SMBus IO port
+ */
+__attribute__ ((weak))
+int smbus_is_busy(u32 smbus_dev)
+{
+ /* Check if bit 0 of the status register is 1 (busy) or 0 (ready) */
+ return ((inb(SMBHSTSTAT(smbus_dev)) & (1 << 0)) == 1);
+}
+
+/**
+ * \brief Wait for the SMBus to become ready to process a new transaction.
+ *
+ * @param smbus_dev The base SMBus IO port
+ */
+__attribute__ ((weak))
+int smbus_wait_until_ready(u32 smbus_dev)
+{
+ int loops;
+
+ printsmbus("Waiting until SMBus ready\n");
+
+ /* Loop up to SMBUS_TIMEOUT times, waiting for bit 0 of the
+ * SMBus Host Status register to go to 0, indicating the operation
+ * was completed successfully. I don't remember why I did it this way,
+ * but I think it was because ROMCC was running low on registers */
+ loops = 0;
+ while (smbus_is_busy(smbus_dev) && loops < SMBUS_TIMEOUT)
+ ++loops;
+
+ return smbus_print_error(smbus_dev, inb(SMBHSTSTAT(smbus_dev)), loops);
+}
+
+/**
+ * \brief Read a byte from the SMBus.
+ *
+ * @param smbus_dev The base SMBus IO port
+ * @param addr The address location of the DIMM on the SMBus.
+ * @param offset The offset the data is located at.
+ */
+__attribute__ ((weak))
+u8 smbus_read_byte(u32 smbus_dev, u8 addr, u8 offset)
+{
+ u8 val;
+
+ /* Initialize SMBus sequence */
+ smbus_reset(smbus_dev);
+ /* Clear host data port. */
+ outb(0x00, SMBHSTDAT0(smbus_dev));
+
+ smbus_wait_until_ready(smbus_dev);
+
+ /* Actual addr to reg format. */
+ addr = (addr << 1);
+ addr |= 1; /* read command */
+ outb(addr, SMBXMITADD(smbus_dev));
+ outb(offset, SMBHSTCMD(smbus_dev));
+ /* Start transaction, byte data read. */
+ outb(0x48, SMBHSTCTL(smbus_dev));
+ smbus_wait_until_ready(smbus_dev);
+
+ val = inb(SMBHSTDAT0(smbus_dev));
+ return val;
+}
Alexandru Gagniuc (mr.nuke.me(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/143
-gerrit
commit ab6ff9eb9e7a41e20da4f4ff7547adaa947690f2
Author: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
Date: Tue May 21 12:17:58 2013 -0500
coreboot: Add generic early SMBus API
Early SMBUS code with similar functionality is duplicated for all
southbridges. Add a generic SMBus API (function declarations) designed to
unify the early SMBus structure.
This patch only adds the API. It does not implement any hardware-specific
bits.
Change-Id: I0861b7a3f098115182ae6de9f016dd671c500bad
Signed-off-by: Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
---
src/include/device/early_smbus.h | 73 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
diff --git a/src/include/device/early_smbus.h b/src/include/device/early_smbus.h
new file mode 100644
index 0000000..77c9078
--- /dev/null
+++ b/src/include/device/early_smbus.h
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 Alexandru Gagniuc <mr.nuke.me(a)gmail.com>
+ *
+ * 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, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file early_smbus.h
+ *
+ * This file defines a common API for accessing the SMBus during early
+ * initialization. It defines the prototypes for common SMBus functions. The
+ * actual implementations are hardware-dependent.
+ *
+ * The first parameter of all SMBus functions take a u32 value smbus_dev which
+ * represents some information on how to access the device, and is
+ * implementation defined. Usually, it just contains the IO base for the smbus.
+ * To get this argument @ref smbus_get_device() can be used.
+ *
+ * The header only defines the prototypes. Several steps are needed to use
+ * these:
+ *
+ * 1. Include this header
+ * @code{.c}
+ * #include <device/early_smbus.h>
+ * @endcode
+ *
+ * 2. Implement early_smbus.c for the hardware, or find a compatible
+ * implementation.
+ *
+ * 3. Link against the file that implements these functions. In the Makefile.inc
+ * of the chipset, add:
+ * @code
+ * romstage-y += ./path/to/early_smbus.c
+ * @endcode
+ */
+
+#ifndef DEVICE_EARLY_SMBUS_H
+#define DEVICE_EARLY_SMBUS_H
+
+#include <stdint.h>
+
+/**
+ * \brief printk macro for SMBus debugging
+ */
+#if defined(CONFIG_DEBUG_SMBUS_SETUP) && (CONFIG_DEBUG_SMBUS_SETUP)
+#define printsmbus(x, ...) printk(BIOS_DEBUG, x, ##__VA_ARGS__)
+#else
+#define printsmbus(x, ...)
+#endif
+
+u32 smbus_get_device(void);
+void smbus_reset(u32 smbus_dev);
+int smbus_print_error(u32 smbus_dev, u8 host_status, int loops);
+int smbus_is_busy(u32 smbus_dev);
+int smbus_wait_until_ready(u32 smbus_dev);
+u8 smbus_read_byte(u32 smbus_dev, u8 addr, u8 offset);
+
+void smbus_delay(void);
+
+#endif /* DEVICE_EARLY_SMBUS_H */