diff options
author | Stefan Reinauer <reinauer@chromium.org> | 2012-03-30 17:06:43 -0700 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2012-04-02 18:42:40 +0200 |
commit | 020b22a5c4efd82937706372817fc441c5345d68 (patch) | |
tree | 0c076de171bb08ac750ab5dbc45586ba3fee58ce /src/ec/smsc/mec1308 | |
parent | b0dd1d91f49eef80016a60bb09e2c1a8cfcc628e (diff) | |
download | coreboot-020b22a5c4efd82937706372817fc441c5345d68.tar.xz |
Add EC component for SMSC MEC1308/1310
Change-Id: I92109fb633a1a3090b4b1767dd119b8c8a1b5f81
Signed-off-by: Duncan Laurie <dlaurie@google.com>
Signed-off-by: Stefan Reinauer <reinauer@google.com>
Reviewed-on: http://review.coreboot.org/828
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src/ec/smsc/mec1308')
-rw-r--r-- | src/ec/smsc/mec1308/Kconfig | 4 | ||||
-rw-r--r-- | src/ec/smsc/mec1308/Makefile.inc | 2 | ||||
-rw-r--r-- | src/ec/smsc/mec1308/acpi/ac.asl | 38 | ||||
-rw-r--r-- | src/ec/smsc/mec1308/acpi/battery.asl | 196 | ||||
-rw-r--r-- | src/ec/smsc/mec1308/acpi/ec.asl | 272 | ||||
-rw-r--r-- | src/ec/smsc/mec1308/chip.h | 33 | ||||
-rw-r--r-- | src/ec/smsc/mec1308/ec.c | 135 | ||||
-rw-r--r-- | src/ec/smsc/mec1308/ec.h | 41 |
8 files changed, 721 insertions, 0 deletions
diff --git a/src/ec/smsc/mec1308/Kconfig b/src/ec/smsc/mec1308/Kconfig new file mode 100644 index 0000000000..0a0b04aa39 --- /dev/null +++ b/src/ec/smsc/mec1308/Kconfig @@ -0,0 +1,4 @@ +config EC_SMSC_MEC1308 + bool + help + Shared memory mailbox interface to SMSC MEC1308 Embedded Controller. diff --git a/src/ec/smsc/mec1308/Makefile.inc b/src/ec/smsc/mec1308/Makefile.inc new file mode 100644 index 0000000000..95c6c030d2 --- /dev/null +++ b/src/ec/smsc/mec1308/Makefile.inc @@ -0,0 +1,2 @@ +driver-y += ec.c +smm-y += ec.c diff --git a/src/ec/smsc/mec1308/acpi/ac.asl b/src/ec/smsc/mec1308/acpi/ac.asl new file mode 100644 index 0000000000..d14f3a4ae3 --- /dev/null +++ b/src/ec/smsc/mec1308/acpi/ac.asl @@ -0,0 +1,38 @@ +/* + * 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 + */ + +// Scope (EC0) + +Device (AC) +{ + Name (_HID, "ACPI0003") + Name (_PCL, Package () { \_SB }) + + Method (_PSR) + { + Return (ACEX) + } + + Method (_STA) + { + Return (0x0F) + } +} diff --git a/src/ec/smsc/mec1308/acpi/battery.asl b/src/ec/smsc/mec1308/acpi/battery.asl new file mode 100644 index 0000000000..9b2f93be53 --- /dev/null +++ b/src/ec/smsc/mec1308/acpi/battery.asl @@ -0,0 +1,196 @@ +/* + * 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 + */ + +/* + * The mainboard must define strings in the root scope to + * report device-specific battery information to the OS. + * + * BATM: Model + * BATS: Serial + * BATV: Vendor + */ + +// Scope (EC0) + +Device (BAT0) +{ + Name (_HID, EISAID ("PNP0C0A")) + Name (_UID, 1) + Name (_PCL, Package () { \_SB }) + + Name (PBIF, Package () { + 0x00000001, // Power Unit: mAh + 0xFFFFFFFF, // Design Capacity + 0xFFFFFFFF, // Last Full Charge Capacity + 0x00000001, // Battery Technology: Rechargeable + 0xFFFFFFFF, // Design Voltage + 0x00000003, // Design Capacity of Warning + 0xFFFFFFFF, // Design Capacity of Low + 0x00000001, // Capacity Granularity 1 + 0x00000001, // Capacity Granularity 2 + "", // Model Number + "", // Serial Number + "LION", // Battery Type + "" // OEM Information + }) + + Name (PBST, Package () { + 0x00000000, // Battery State + 0xFFFFFFFF, // Battery Present Rate + 0xFFFFFFFF, // Battery Remaining Capacity + 0xFFFFFFFF, // Battery Present Voltage + }) + Name (BSTP, Zero) + + // Workaround for full battery status, enabled by default + Name (BFWK, One) + + // Method to enable full battery workaround + Method (BFWE) + { + Store (One, BFWK) + } + + // Method to disable full battery workaround + Method (BFWD) + { + Store (Zero, BFWK) + } + + // Swap bytes in a word + Method (SWAB, 1, NotSerialized) + { + ShiftRight (Arg0, 8, Local0) + ShiftLeft (Arg0, 8, Local1) + And (Local1, 0xFF00, Local1) + Or (Local0, Local1, Local0) + If (LEqual (Local0, 0xFFFF)) { + Store (0xFFFFFFFF, Local0) + } + Return (Local0) + } + + Method (_STA, 0, Serialized) + { + If (BTEX) { + Return (0x1F) + } Else { + Return (0x0F) + } + } + + Method (_BIF, 0, Serialized) + { + // Update fields from EC + Store (SWAB (BTDA), Index (PBIF, 1)) + Store (SWAB (BTDF), Index (PBIF, 2)) + Store (SWAB (BTDV), Index (PBIF, 4)) + Store (SWAB (BTDL), Index (PBIF, 6)) + + // Get battery info from mainboard + Store (\BATM, Index (PBIF, 9)) + Store (\BATS, Index (PBIF, 10)) + Store (\BATV, Index (PBIF, 12)) + + Return (PBIF) + } + + Method (_BST, 0, Serialized) + { + // + // 0: BATTERY STATE + // + // bit 0 = discharging + // bit 1 = charging + // bit 2 = critical level + // + + // Get battery state from EC + Store (BTST, Local0) + Store (Zero, Local1) + + // Check if AC is present + If (ACEX) { + // Set only charging/discharging bits + And (Local0, 0x03, Local1) + } Else { + // Always discharging when on battery power + Store (0x01, Local1) + } + + // Flag if the battery level is critical + And (Local0, 0x04, Local4) + Or (Local1, Local4, Local1) + Store (Local1, Index (PBST, 0)) + + // Notify if battery state has changed since last time + If (LNotEqual (Local1, BSTP)) { + Store (Local1, BSTP) + Notify (BAT0, 0x80) + } + + // + // 1: BATTERY PRESENT RATE + // + + Store (SWAB (BTPR), Local1) + If (LAnd (LNotEqual (Local1, 0xFFFFFFFF), + LGreaterEqual (Local1, 0x8000))) { + Xor (Local1, 0xFFFF, Local1) + Increment (Local1) + } + Store (Local1, Index (PBST, 1)) + + // + // 2: BATTERY REMAINING CAPACITY + // + Store (SWAB (BTRA), Local1) + If (LAnd (LNotEqual (Local1, 0xFFFFFFFF), + LGreaterEqual (Local1, 0x8000))) { + Xor (Local1, 0xFFFF, Local1) + Increment (Local1) + } + + If (LAnd (BFWK, LAnd (ACEX, LNot (Local0)))) { + // On AC power and battery is neither charging + // nor discharging. Linux expects a full battery + // to report same capacity as last full charge. + // https://bugzilla.kernel.org/show_bug.cgi?id=12632 + Store (SWAB (BTDF), Local2) + + // See if within ~3% of full + ShiftRight (Local2, 5, Local3) + If (LAnd (LGreater (Local1, Subtract (Local2, Local3)), + LLess (Local1, Add (Local2, Local3)))) + { + Store (Local2, Local1) + } + } + Store (Local1, Index (PBST, 2)) + + // + // 3: BATTERY PRESENT VOLTAGE + // + Store (SWAB (BTVO), Index (PBST, 3)) + + Return (PBST) + } +} diff --git a/src/ec/smsc/mec1308/acpi/ec.asl b/src/ec/smsc/mec1308/acpi/ec.asl new file mode 100644 index 0000000000..f0b77c25e5 --- /dev/null +++ b/src/ec/smsc/mec1308/acpi/ec.asl @@ -0,0 +1,272 @@ +/* + * 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 + */ + +/* + * The mainboard must define a PNOT method to handle power + * state notifications and Notify CPU device objects to + * re-evaluate their _PPC and _CST tables. + */ + +Device (EC0) +{ + Name (_HID, EISAID ("PNP0C09")) + Name (_UID, 1) + Name (_GPE, EC_GPE) // GPE for Runtime SCI + + OperationRegion (ERAM, EmbeddedControl, 0x00, 0xff) + Field (ERAM, ByteAcc, Lock, Preserve) + { + Offset (0x80), + BTEX, 1, // Battery Exists + , 1, + ACEX, 1, // AC Exists + , 5, + Offset (0x83), + LIDS, 1, // Lid Switch State + , 7, + BTST, 8, // Battery State + Offset (0xA2), + BTRA, 16, // Battery Remaining Capacity + BTPR, 16, // Battery Present Rate + BTVO, 16, // Battery Present Voltage + Offset (0xB0), + BTDA, 16, // Battery Design Capacity + BTDF, 16, // Battery Last Full Charge Capacity + BTDV, 16, // Battery Design Voltage + BTDL, 16, // Battery Design Low + Offset (0xC0), + CPUT, 8, // CPU Temperature + Offset (0xCA), + FSL0, 1, // Fan Speed Level 0 + FSL1, 1, // Fan Speed Level 1 + FSL2, 1, // Fan Speed Level 2 + FSL3, 1, // Fan Speed Level 3 + FSL4, 1, // Fan Speed Level 4 + , 2, + FCOS, 1, // Fan Speed OS Control + } + + Method (_CRS, 0, NotSerialized) + { + Name (ECMD, ResourceTemplate() + { + IO (Decode16, 0x62, 0x62, 0, 1) + IO (Decode16, 0x66, 0x66, 0, 1) + }) + Return (ECMD) + } + + Method (_REG, 2, NotSerialized) + { + // Initialize AC power state + Store (ACEX, \PWRS) + + // Initialize LID switch state + Store (LIDS, \LIDS) + + // Enable OS control of fan speed + Store (One, FCOS) + + // Force a read of CPU temperature + Store (CPUT, Local0) + } + + PowerResource (FNP0, 0, 0) + { + Method (_STA) { Return (FSL0) } + Method (_ON) { + If (FCOS) { + Store (One, FSL0) + Store (0, \FLVL) + Notify (\_TZ.THRM, 0x81) + } + } + Method (_OFF) { + If (FCOS) { + Store (Zero, FSL0) + Store (1, \FLVL) + Notify (\_TZ.THRM, 0x81) + } + } + } + + PowerResource (FNP1, 0, 0) + { + Method (_STA) { Return (FSL1) } + Method (_ON) { + If (FCOS) { + Store (One, FSL1) + Store (1, \FLVL) + Notify (\_TZ.THRM, 0x81) + } + } + Method (_OFF) { + If (FCOS) { + Store (Zero, FSL1) + Store (2, \FLVL) + Notify (\_TZ.THRM, 0x81) + } + } + } + + PowerResource (FNP2, 0, 0) + { + Method (_STA) { Return (FSL2) } + Method (_ON) { + If (FCOS) { + Store (One, FSL2) + Store (2, \FLVL) + Notify (\_TZ.THRM, 0x81) + } + } + Method (_OFF) { + If (FCOS) { + Store (Zero, FSL2) + Store (3, \FLVL) + Notify (\_TZ.THRM, 0x81) + } + } + } + + PowerResource (FNP3, 0, 0) + { + Method (_STA) { Return (FSL3) } + Method (_ON) { + If (FCOS) { + Store (One, FSL3) + Store (3, \FLVL) + Notify (\_TZ.THRM, 0x81) + } + } + Method (_OFF) { + If (FCOS) { + Store (Zero, FSL3) + Store (4, \FLVL) + Notify (\_TZ.THRM, 0x81) + } + } + } + + PowerResource (FNP4, 0, 0) + { + Method (_STA) { Return (FSL4) } + Method (_ON) { + If (FCOS) { + Store (One, FSL4) + Store (4, \FLVL) + Notify (\_TZ.THRM, 0x81) + } + } + Method (_OFF) { + If (FCOS) { + Store (Zero, FSL4) + Store (5, \FLVL) + Notify (\_TZ.THRM, 0x81) + } + } + } + + Device (FAN0) + { + Name (_HID, EISAID ("PNP0C0B")) + Name (_UID, 0) + Name (_PR0, Package () { FNP0 }) + } + + Device (FAN1) + { + Name (_HID, EISAID ("PNP0C0B")) + Name (_UID, 1) + Name (_PR0, Package () { FNP1 }) + } + + Device (FAN2) + { + Name (_HID, EISAID ("PNP0C0B")) + Name (_UID, 2) + Name (_PR0, Package () { FNP2 }) + } + + Device (FAN3) + { + Name (_HID, EISAID ("PNP0C0B")) + Name (_UID, 3) + Name (_PR0, Package () { FNP3 }) + } + + Device (FAN4) + { + Name (_HID, EISAID ("PNP0C0B")) + Name (_UID, 4) + Name (_PR0, Package () { FNP4 }) + } + + // AC Power Connected + Method (_Q51, 0, NotSerialized) + { + Store (One, \PWRS) + Notify (AC, 0x80) + \PNOT () + } + + // AC Power Removed + Method (_Q52, 0, NotSerialized) + { + Store (Zero, \PWRS) + Notify (AC, 0x80) + \PNOT () + } + + // Battery State Change + Method (_Q53, 0, NotSerialized) + { + Notify (BAT0, 0x80) + Notify (BAT0, 0x81) + } + + // Battery State Change + Method (_Q54, 0, NotSerialized) + { + Notify (BAT0, 0x80) + Notify (BAT0, 0x81) + } + + // Power State Change + Method (_Q55, 0, NotSerialized) + { + \PNOT () + } + + // Lid Switch Event + Method (_Q5E, 0, NotSerialized) + { + Store (LIDS, \LIDS) + Notify (\_SB.LID0, 0x80) + } + + // Lid Switch Event + Method (_Q5F, 0, NotSerialized) + { + Store (LIDS, \LIDS) + Notify (\_SB.LID0, 0x80) + } + + #include "ac.asl" + #include "battery.asl" +} diff --git a/src/ec/smsc/mec1308/chip.h b/src/ec/smsc/mec1308/chip.h new file mode 100644 index 0000000000..3a8eae8f8a --- /dev/null +++ b/src/ec/smsc/mec1308/chip.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 _EC_SMSC_MEC1308_CHIP_H +#define _EC_SMSC_MEC1308_CHIP_H + +struct ec_smsc_mec1308_config +{ + u16 mailbox_port; +}; + +struct chip_operations; +extern struct chip_operations ec_smsc_mec1308_ops; + +#endif /* _EC_SMSC_MEC1308_CHIP_H */ diff --git a/src/ec/smsc/mec1308/ec.c b/src/ec/smsc/mec1308/ec.c new file mode 100644 index 0000000000..bfd3c14bca --- /dev/null +++ b/src/ec/smsc/mec1308/ec.c @@ -0,0 +1,135 @@ +/* + * 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 + */ + +#include <console/console.h> +#include <device/device.h> +#include <arch/io.h> +#include <delay.h> +#include "ec.h" +#include "chip.h" + +static u16 ec_cmd_reg = 0; +static u16 ec_data_reg = 0; + +static inline u8 __ec_read(u8 addr) +{ + outb(addr, ec_cmd_reg); + return inb(ec_data_reg); +} + +static inline void __ec_write(u8 addr, u8 data) +{ + outb(addr, ec_cmd_reg); + outb(data, ec_data_reg); +} + +static int ec_ready(void) +{ + u16 timeout = EC_TIMEOUT; + + if (!ec_cmd_reg || !ec_data_reg) { + printk(BIOS_DEBUG, "Invalid ports: cmd=0x%x data=0x%x\n", + ec_cmd_reg, ec_data_reg); + return -1; + } + + while (__ec_read(EC_MAILBOX_COMMAND) != 0 && --timeout) { + udelay(10); + if ((timeout & 0xff) == 0) + printk(BIOS_SPEW, "."); + } + if (!timeout) { + printk(BIOS_DEBUG, "Timeout waiting for EC to be ready.\n"); + return -1; + } + return 0; +} + +int send_ec_command(u8 command) +{ + if (ec_ready() < 0) + return -1; + __ec_write(EC_MAILBOX_COMMAND, command); + return ec_ready(); +} + +int send_ec_command_data(u8 command, u8 data) +{ + if (ec_ready() < 0) + return -1; + __ec_write(EC_MAILBOX_DATA, data); + __ec_write(EC_MAILBOX_COMMAND, command); + return ec_ready(); +} + +u8 read_ec_command_byte(u8 command) +{ + send_ec_command(command); + return __ec_read(EC_MAILBOX_DATA); +} + +u8 ec_read(u8 addr) +{ + if (send_ec_command_data(EC_RAM_READ, addr) < 0) + return 0; + return __ec_read(EC_MAILBOX_DATA); +} + +int ec_write(u8 addr, u8 data) +{ + if (ec_ready() < 0) + return -1; + __ec_write(EC_MAILBOX_DATA, addr); + __ec_write(EC_MAILBOX_DATA_H, data); + __ec_write(EC_MAILBOX_COMMAND, EC_RAM_WRITE); + return ec_ready(); +} + +void ec_set_bit(u8 addr, u8 bit) +{ + ec_write(addr, ec_read(addr) | (1 << bit)); +} + +void ec_clr_bit(u8 addr, u8 bit) +{ + ec_write(addr, ec_read(addr) & ~(1 << bit)); +} + +void ec_set_ports(u16 cmd_reg, u16 data_reg) +{ + ec_cmd_reg = cmd_reg; + ec_data_reg = data_reg; +} + +static void mec1308_enable(device_t dev) +{ + struct ec_smsc_mec1308_config *conf = dev->chip_info; + + if (conf->mailbox_port) { + ec_cmd_reg = conf->mailbox_port; + ec_data_reg = conf->mailbox_port + 1; + } +} + +struct chip_operations ec_smsc_mec1308_ops = { + CHIP_NAME("SMSC MEC1308 EC Mailbox Interface") + .enable_dev = mec1308_enable +}; diff --git a/src/ec/smsc/mec1308/ec.h b/src/ec/smsc/mec1308/ec.h new file mode 100644 index 0000000000..07bfc4f786 --- /dev/null +++ b/src/ec/smsc/mec1308/ec.h @@ -0,0 +1,41 @@ +/* + * 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 + * + * Mailbox EC communication interface for SMSC MEC1308 Embedded Controller. + */ + +#ifndef _EC_SMSC_MEC1308_EC_H +#define _EC_SMSC_MEC1308_EC_H + +#define EC_TIMEOUT 0xfff +#define EC_MAILBOX_COMMAND 0x82 // Send a command +#define EC_MAILBOX_DATA 0x84 // Send data with a command +#define EC_MAILBOX_DATA_H 0x85 // Send data with a command +#define EC_RAM_READ 0x88 // Read from RAM +#define EC_RAM_WRITE 0x89 // Write to RAM + +int send_ec_command(u8 command); +int send_ec_command_data(u8 command, u8 data); +u8 read_ec_command_byte(u8 command); +u8 ec_read(u8 addr); +int ec_write(u8 addr, u8 data); +void ec_set_bit(u8 addr, u8 bit); +void ec_clr_bit(u8 addr, u8 bit); +void ec_set_ports(u16 cmd_reg, u16 data_reg); + +#endif /* _EC_SMSC_MEC1308_EC_H */ |