summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNicholas Chin <nic.c3.14@gmail.com>2021-11-27 22:06:00 -0700
committerFelix Held <felix-coreboot@felixheld.de>2023-02-08 19:21:59 +0000
commite0e6bccd4423f44188a45c2c3841c0b2c6825854 (patch)
treeaf665907c8f074904bcd3064ffbe16bdcc2f7c50 /src
parent6bd733b7d4be6416f2de45a91c23b3cd7f071a5b (diff)
ec/dell: Add support for the SMSC MEC5035
This is required to prevent the EC from shutting down the system after about 15 seconds after being turned on. If the EC doesn't receive a command meaning "CPU OK" it assumes that the processor has failed and flashes a diagnostic code on the keyboard LEDs to indicate this. This also enables the keyboard and trackpad/trackpoint interfaces. Parts of this code were derived from yet-to-be merged code in CB:44975 (ec: Add support for MEC5055 for Dell laptops) written by Iru Cai. Tested on a Dell Latitude E6400 Signed-off-by: Nicholas Chin <nic.c3.14@gmail.com> Change-Id: Ia420cd51e9a64be5eee4af2c0d113618575522b0 Reviewed-on: https://review.coreboot.org/c/coreboot/+/59703 Reviewed-by: Angel Pons <th3fanbus@gmail.com> Reviewed-by: Paul Menzel <paulepanter@mailbox.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src')
-rw-r--r--src/ec/dell/mec5035/Kconfig4
-rw-r--r--src/ec/dell/mec5035/Makefile.inc9
-rw-r--r--src/ec/dell/mec5035/mec5035.c122
-rw-r--r--src/ec/dell/mec5035/mec5035.h23
4 files changed, 158 insertions, 0 deletions
diff --git a/src/ec/dell/mec5035/Kconfig b/src/ec/dell/mec5035/Kconfig
new file mode 100644
index 0000000000..220714371d
--- /dev/null
+++ b/src/ec/dell/mec5035/Kconfig
@@ -0,0 +1,4 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+config EC_DELL_MEC5035
+ bool
diff --git a/src/ec/dell/mec5035/Makefile.inc b/src/ec/dell/mec5035/Makefile.inc
new file mode 100644
index 0000000000..4ebdd811f9
--- /dev/null
+++ b/src/ec/dell/mec5035/Makefile.inc
@@ -0,0 +1,9 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+ifeq ($(CONFIG_EC_DELL_MEC5035),y)
+
+bootblock-y += mec5035.c
+romstage-y += mec5035.c
+ramstage-y += mec5035.c
+
+endif
diff --git a/src/ec/dell/mec5035/mec5035.c b/src/ec/dell/mec5035/mec5035.c
new file mode 100644
index 0000000000..8da11e5b1c
--- /dev/null
+++ b/src/ec/dell/mec5035/mec5035.c
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pnp.h>
+#include <pc80/keyboard.h>
+#include <stdint.h>
+#include "mec5035.h"
+
+static const u16 MAILBOX_INDEX = 0x910;
+static const u16 MAILBOX_DATA = MAILBOX_INDEX + 1;
+
+static inline u8 __get_mailbox_register(u8 index)
+{
+ outb(index + 0x10, MAILBOX_INDEX);
+ return inb(MAILBOX_DATA);
+}
+
+static inline void __set_mailbox_register(u8 index, u8 data)
+{
+ outb(index + 0x10, MAILBOX_INDEX);
+ outb(data, MAILBOX_DATA);
+}
+
+static void wait_ec(void)
+{
+ u8 busy;
+ do {
+ outb(0, MAILBOX_INDEX);
+ busy = inb(MAILBOX_DATA);
+ } while (busy);
+}
+
+
+static enum cb_err read_mailbox_regs(u8 *data, u8 start, u8 count)
+{
+ if (start + count >= NUM_REGISTERS) {
+ printk(BIOS_ERR, "%s: Invalid start or count argument.\n", __func__);
+ return CB_ERR_ARG;
+ }
+
+ while (count--) {
+ *data = __get_mailbox_register(start);
+ data++;
+ start++;
+ }
+
+ return CB_SUCCESS;
+}
+
+static enum cb_err write_mailbox_regs(const u8 *data, u8 start, u8 count)
+{
+ if (start + count >= NUM_REGISTERS) {
+ printk(BIOS_ERR, "%s: Invalid start or count argument.\n", __func__);
+ return CB_ERR_ARG;
+ }
+
+ while (count--) {
+ __set_mailbox_register(start, *data);
+ data++;
+ start++;
+ }
+
+ return CB_SUCCESS;
+}
+
+static void ec_command(u8 cmd)
+{
+ outb(0, MAILBOX_INDEX);
+ outb(cmd, MAILBOX_DATA);
+ wait_ec();
+}
+
+u8 mec5035_mouse_touchpad(u8 setting)
+{
+ u8 buf[15] = {0};
+ write_mailbox_regs(&setting, 2, 1);
+ ec_command(CMD_MOUSE_TP);
+ /* The vendor firmware reads 15 bytes starting at index 1, presumably
+ to get some sort of return code. Though I don't know for sure if
+ this is the case. Assume the first byte is the return code. */
+ read_mailbox_regs(buf, 1, 15);
+ return buf[0];
+}
+
+void mec5035_early_init(void)
+{
+ /* If this isn't sent the EC shuts down the system after about 15
+ seconds, flashing a pattern on the keyboard LEDs corresponding
+ to "processor failure" according to Dell service manuals. */
+ ec_command(CMD_CPU_OK);
+}
+
+static void mec5035_init(struct device *dev)
+{
+ /* Unconditionally use this argument for now as this setting
+ is probably the most sensible default out of the 3 choices. */
+ mec5035_mouse_touchpad(TP_PS2_MOUSE);
+
+ pc_keyboard_init(NO_AUX_DEVICE);
+}
+
+static struct device_operations ops = {
+ .init = mec5035_init,
+ .read_resources = noop_read_resources,
+ .set_resources = noop_set_resources
+};
+
+static struct pnp_info pnp_dev_info[] = {
+ { NULL, 0, 0, 0, }
+};
+
+static void mec5035_enable(struct device *dev)
+{
+ pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
+}
+
+struct chip_operations ec_dell_mec5035_ops = {
+ CHIP_NAME("MEC5035 EC")
+ .enable_dev = mec5035_enable,
+};
diff --git a/src/ec/dell/mec5035/mec5035.h b/src/ec/dell/mec5035/mec5035.h
new file mode 100644
index 0000000000..e7a05b64d4
--- /dev/null
+++ b/src/ec/dell/mec5035/mec5035.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _EC_DELL_MEC5035_H_
+#define _EC_DELL_MEC5035_H_
+
+#include <stdint.h>
+
+#define NUM_REGISTERS 32
+
+/* Touchpad (TP) and mouse related. The EC seems to
+ default to 0 which results in the TP not working. */
+#define CMD_MOUSE_TP 0x1a
+#define SERIAL_MOUSE 0 /* Disable TP, force use of a serial mouse */
+#define PS2_MOUSE 1 /* Disable TP when using a PS/2 mouse */
+#define TP_PS2_MOUSE 2 /* Leave TP enabled when using a PS/2 mouse */
+
+#define CMD_CPU_OK 0xc2
+
+u8 mec5035_mouse_touchpad(u8 setting);
+void mec5035_cpu_ok(void);
+void mec5035_early_init(void);
+
+#endif /* _EC_DELL_MEC5035_H_ */