aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mainboard/lippert/frontrunner-af/Makefile.inc4
-rw-r--r--src/mainboard/lippert/frontrunner-af/mainboard.c33
-rw-r--r--src/mainboard/lippert/frontrunner-af/sema.c89
-rw-r--r--src/mainboard/lippert/frontrunner-af/sema.h23
-rw-r--r--src/mainboard/lippert/toucan-af/Makefile.inc4
-rw-r--r--src/mainboard/lippert/toucan-af/mainboard.c34
6 files changed, 132 insertions, 55 deletions
diff --git a/src/mainboard/lippert/frontrunner-af/Makefile.inc b/src/mainboard/lippert/frontrunner-af/Makefile.inc
index ba56286636..3ea57cd1e3 100644
--- a/src/mainboard/lippert/frontrunner-af/Makefile.inc
+++ b/src/mainboard/lippert/frontrunner-af/Makefile.inc
@@ -27,3 +27,7 @@ romstage-y += OemCustomize.c
ramstage-y += buildOpts.c
ramstage-y += BiosCallOuts.c
ramstage-y += OemCustomize.c
+
+# Minimal SEMA watchdog support
+romstage-y += sema.c
+ramstage-y += sema.c
diff --git a/src/mainboard/lippert/frontrunner-af/mainboard.c b/src/mainboard/lippert/frontrunner-af/mainboard.c
index a846528f5b..1212764cae 100644
--- a/src/mainboard/lippert/frontrunner-af/mainboard.c
+++ b/src/mainboard/lippert/frontrunner-af/mainboard.c
@@ -27,6 +27,7 @@
#include "SBPLATFORM.h"
#include "OEM.h" /* SMBUS0_BASE_ADDRESS */
#include <southbridge/amd/cimx/sb800/gpio_oem.h>
+#include "sema.h"
/* Init SIO GPIOs. */
#define SIO_RUNTIME_BASE 0x0E00
@@ -59,28 +60,6 @@ static const u16 sio_init_table[] = { // hi = offset, lo = value
0x5780, // GP65: USB power 4/5 = open drain output
};
-/* Write data block to slave on SMBUS0. */
-#define SMB0_STATUS ((SMBUS0_BASE_ADDRESS) + 0)
-#define SMB0_CONTROL ((SMBUS0_BASE_ADDRESS) + 2)
-#define SMB0_HOSTCMD ((SMBUS0_BASE_ADDRESS) + 3)
-#define SMB0_ADDRESS ((SMBUS0_BASE_ADDRESS) + 4)
-#define SMB0_DATA0 ((SMBUS0_BASE_ADDRESS) + 5)
-#define SMB0_BLOCKDATA ((SMBUS0_BASE_ADDRESS) + 7)
-static int smb_write_blk(u8 slave, u8 command, u8 length, const u8 *data)
-{
- __outbyte(SMB0_STATUS, 0x1E); // clear error status
- __outbyte(SMB0_ADDRESS, slave & ~1); // slave addr + direction = out
- __outbyte(SMB0_HOSTCMD, command); // or destination offset
- __outbyte(SMB0_DATA0, length); // sent before data
- __inbyte(SMB0_CONTROL); // reset block data array
- while (length--)
- __outbyte(SMB0_BLOCKDATA, *(data++));
- __outbyte(SMB0_CONTROL, 0x54); // execute block write, no IRQ
-
- while (__inbyte(SMB0_STATUS) == 0x01); // busy, no errors
- return __inbyte(SMB0_STATUS) ^ 0x02; // 0x02 = completed, no errors
-}
-
static void init(struct device *dev)
{
volatile u8 *spi_base; // base addr of Hudson's SPI host controller
@@ -126,11 +105,11 @@ static void init(struct device *dev)
/* Notify the SMC we're alive and kicking, or after a while it will
* effect a power cycle and switch to the alternate BIOS chip.
- * Should be done as late as possible. */
- printk(BIOS_INFO, "Sending BIOS alive message\n");
- const u8 i_am_alive[] = { 0x03 };
- if ((i = smb_write_blk(0x50, 0x25, sizeof(i_am_alive), i_am_alive)))
- printk(BIOS_ERR, "smb_write_blk failed: %d\n", i);
+ * Should be done as late as possible.
+ * Failure here does not matter if watchdog was already disabled,
+ * by configuration or previous boot, so ignore return value.
+ */
+ sema_send_alive();
printk(BIOS_DEBUG, CONFIG_MAINBOARD_PART_NUMBER " EXIT %s\n", __func__);
}
diff --git a/src/mainboard/lippert/frontrunner-af/sema.c b/src/mainboard/lippert/frontrunner-af/sema.c
new file mode 100644
index 0000000000..3a4994de1d
--- /dev/null
+++ b/src/mainboard/lippert/frontrunner-af/sema.c
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdlib.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <delay.h>
+#include "OEM.h" /* SMBUS0_BASE_ADDRESS */
+
+#include "Porting.h"
+#include "AGESA.h"
+#include <northbridge/amd/agesa/dimmSpd.h>
+#include "sema.h"
+
+/* Write data block to slave on SMBUS0. */
+#define SMB0_STATUS ((SMBUS0_BASE_ADDRESS) + 0)
+#define SMB0_CONTROL ((SMBUS0_BASE_ADDRESS) + 2)
+#define SMB0_HOSTCMD ((SMBUS0_BASE_ADDRESS) + 3)
+#define SMB0_ADDRESS ((SMBUS0_BASE_ADDRESS) + 4)
+#define SMB0_DATA0 ((SMBUS0_BASE_ADDRESS) + 5)
+#define SMB0_BLOCKDATA ((SMBUS0_BASE_ADDRESS) + 7)
+
+static int smb_write_blk(u8 slave, u8 command, u8 length, const u8 *data)
+{
+ __outbyte(SMB0_STATUS, 0x1E); // clear error status
+ __outbyte(SMB0_ADDRESS, slave & ~1); // slave addr + direction = out
+ __outbyte(SMB0_HOSTCMD, command); // or destination offset
+ __outbyte(SMB0_DATA0, length); // sent before data
+ __inbyte(SMB0_CONTROL); // reset block data array
+ while (length--)
+ __outbyte(SMB0_BLOCKDATA, *(data++));
+ __outbyte(SMB0_CONTROL, 0x54); // execute block write, no IRQ
+
+ while (__inbyte(SMB0_STATUS) == 0x01); // busy, no errors
+ return __inbyte(SMB0_STATUS) ^ 0x02; // 0x02 = completed, no errors
+}
+
+#define RETRY_COUNT 100
+
+/* Use of mdelay() here would fail in romstage. */
+static void early_mdelay(int msecs)
+{
+ while (msecs--) {
+ int i;
+ for (i = 0; i < 1000; i++)
+ inb(0x80);
+ }
+}
+
+int sema_send_alive(void)
+{
+ const u8 i_am_alive[] = { 0x03 };
+ int i, j = 0;
+ char one_spd_byte;
+
+ /* Fake read just to setup SMBUS controller. */
+ if (ENV_ROMSTAGE)
+ smbus_readSpd(0xa0, &one_spd_byte, 1);
+
+ /* Notify the SMC we're alive and kicking, or after a while it will
+ * effect a power cycle and switch to the alternate BIOS chip.
+ * Should be done as late as possible. */
+
+ printk(BIOS_CRIT, "Sending BIOS alive message... ");
+
+ do {
+ i = smb_write_blk(0x50, 0x25, sizeof(i_am_alive), i_am_alive);
+ early_mdelay(25);
+ } while ((++j < RETRY_COUNT) && i);
+
+ if (j == RETRY_COUNT) {
+ printk(BIOS_INFO, "failed\n");
+ return -1;
+ }
+ printk(BIOS_CRIT, "took %d tries\n", j);
+
+ return 0;
+}
diff --git a/src/mainboard/lippert/frontrunner-af/sema.h b/src/mainboard/lippert/frontrunner-af/sema.h
new file mode 100644
index 0000000000..ea8ee31e4e
--- /dev/null
+++ b/src/mainboard/lippert/frontrunner-af/sema.h
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __LIPPERT_SEMA_H__
+#define __LIPPERT_SEMA_H__
+
+/* Signal SEMA watchdog a successful boot.
+ * Returns < 0 is SMBus message failed after
+ * several retries.
+ */
+int sema_send_alive(void);
+
+#endif
diff --git a/src/mainboard/lippert/toucan-af/Makefile.inc b/src/mainboard/lippert/toucan-af/Makefile.inc
index ba56286636..1080c64ded 100644
--- a/src/mainboard/lippert/toucan-af/Makefile.inc
+++ b/src/mainboard/lippert/toucan-af/Makefile.inc
@@ -27,3 +27,7 @@ romstage-y += OemCustomize.c
ramstage-y += buildOpts.c
ramstage-y += BiosCallOuts.c
ramstage-y += OemCustomize.c
+
+# Minimal SEMA watchdog support
+romstage-y += ../frontrunner-af/sema.c
+ramstage-y += ../frontrunner-af/sema.c
diff --git a/src/mainboard/lippert/toucan-af/mainboard.c b/src/mainboard/lippert/toucan-af/mainboard.c
index 7647ebee4f..fa5eb41874 100644
--- a/src/mainboard/lippert/toucan-af/mainboard.c
+++ b/src/mainboard/lippert/toucan-af/mainboard.c
@@ -27,33 +27,11 @@
#include "SBPLATFORM.h"
#include "OEM.h" /* SMBUS0_BASE_ADDRESS */
#include <southbridge/amd/cimx/sb800/gpio_oem.h>
-
-/* Write data block to slave on SMBUS0. */
-#define SMB0_STATUS ((SMBUS0_BASE_ADDRESS) + 0)
-#define SMB0_CONTROL ((SMBUS0_BASE_ADDRESS) + 2)
-#define SMB0_HOSTCMD ((SMBUS0_BASE_ADDRESS) + 3)
-#define SMB0_ADDRESS ((SMBUS0_BASE_ADDRESS) + 4)
-#define SMB0_DATA0 ((SMBUS0_BASE_ADDRESS) + 5)
-#define SMB0_BLOCKDATA ((SMBUS0_BASE_ADDRESS) + 7)
-static int smb_write_blk(u8 slave, u8 command, u8 length, const u8 *data)
-{
- __outbyte(SMB0_STATUS, 0x1E); // clear error status
- __outbyte(SMB0_ADDRESS, slave & ~1); // slave addr + direction = out
- __outbyte(SMB0_HOSTCMD, command); // or destination offset
- __outbyte(SMB0_DATA0, length); // sent before data
- __inbyte(SMB0_CONTROL); // reset block data array
- while (length--)
- __outbyte(SMB0_BLOCKDATA, *(data++));
- __outbyte(SMB0_CONTROL, 0x54); // execute block write, no IRQ
-
- while (__inbyte(SMB0_STATUS) == 0x01); // busy, no errors
- return __inbyte(SMB0_STATUS) ^ 0x02; // 0x02 = completed, no errors
-}
+#include "mainboard/lippert/frontrunner-af/sema.h"
static void init(struct device *dev)
{
volatile u8 *spi_base; // base addr of Hudson's SPI host controller
- int i;
printk(BIOS_DEBUG, CONFIG_MAINBOARD_PART_NUMBER " ENTER %s\n", __func__);
/* Init Hudson GPIOs. */
@@ -93,11 +71,11 @@ static void init(struct device *dev)
/* Notify the SMC we're alive and kicking, or after a while it will
* effect a power cycle and switch to the alternate BIOS chip.
- * Should be done as late as possible. */
- printk(BIOS_INFO, "Sending BIOS alive message\n");
- const u8 i_am_alive[] = { 0x03 }; //bit2 = SEL_DP0: 0 = DDI2, 1 = LVDS
- if ((i = smb_write_blk(0x50, 0x25, sizeof(i_am_alive), i_am_alive)))
- printk(BIOS_ERR, "smb_write_blk failed: %d\n", i);
+ * Should be done as late as possible.
+ * Failure here does not matter if watchdog was already disabled,
+ * by configuration or previous boot, so ignore return value.
+ */
+ sema_send_alive();
printk(BIOS_DEBUG, CONFIG_MAINBOARD_PART_NUMBER " EXIT %s\n", __func__);
}