diff options
author | Vladimir Serbinenko <phcoder@gmail.com> | 2014-10-15 21:51:47 +0200 |
---|---|---|
committer | Vladimir Serbinenko <phcoder@gmail.com> | 2015-05-29 11:26:29 +0200 |
commit | 3129f792f77e310ea246503f8b68b76fc269cfd2 (patch) | |
tree | 9f7538131d0cbb87e39f19be9c9d0c56fbf80107 /util/autoport/ec_lenovo.go | |
parent | b06a249c3b766531ca247bb1278d34875f0d86e4 (diff) | |
download | coreboot-3129f792f77e310ea246503f8b68b76fc269cfd2.tar.xz |
autoport: Write autoport together with porting guide for sandy/ivybridge.
This should be able to generate bootable ports for sandy/ivy, possible with
minor fixes. Howto is in readme.md
Change-Id: Ia126cf0939ef2dc2cdbb7ea100d2b63ea6b02f28
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-on: http://review.coreboot.org/7131
Tested-by: build bot (Jenkins)
Reviewed-by: Edward O'Callaghan <edward.ocallaghan@koparo.com>
Diffstat (limited to 'util/autoport/ec_lenovo.go')
-rw-r--r-- | util/autoport/ec_lenovo.go | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/util/autoport/ec_lenovo.go b/util/autoport/ec_lenovo.go new file mode 100644 index 0000000000..ab5e7abd8a --- /dev/null +++ b/util/autoport/ec_lenovo.go @@ -0,0 +1,295 @@ +package main + +import "fmt" + +func LenovoEC(ctx Context) { + ap := Create(ctx, "acpi/platform.asl") + defer ap.Close() + + wakeGPE := 13 + + sbGPE := GuessECGPE(ctx) + var GPE int + var GPEUnsure bool + if sbGPE < 0 { + sbGPE = SouthBridge.EncodeGPE(1) + GPE = 1 + GPEUnsure = true + SouthBridge.NeedRouteGPIOManually() + } else { + GPE = SouthBridge.DecodeGPE(sbGPE) + GPEUnsure = false + } + + SouthBridge.EnableGPE(wakeGPE) + SouthBridge.EnableGPE(GPE) + + GPEDefine := DSDTDefine{ + Key: "THINKPAD_EC_GPE", + } + + GPEDefine.Value = fmt.Sprintf("%d", sbGPE) + if GPEUnsure { + GPEDefine.Comment = "FIXME: Check this" + } + + DSDTDefines = append(DSDTDefines, + DSDTDefine{ + Key: "EC_LENOVO_H8_ME_WORKAROUND", + Value: "1", + }, GPEDefine) + + ap.WriteString( + `Method(_WAK,1) +{ + /* ME may not be up yet. */ + Store (0, \_TZ.MEB1) + Store (0, \_TZ.MEB2) + Return(Package(){0,0}) +} + +Method(_PTS,1) +{ + \_SB.PCI0.LPCB.EC.RADI(0) +} +`) + + si := Create(ctx, "acpi/superio.asl") + defer si.Close() + + si.WriteString("#include <drivers/pc80/ps2_controller.asl>\n") + + dock := Create(ctx, "dock.c") + defer dock.Close() + + AddRAMStageFile("dock.c", "") + + dock.WriteString( + `#include <ec/lenovo/h8/h8.h> + +void h8_mainboard_init_dock (void) +{ +/* FIXME: fill this if needed. */ +} +`) + + /* FIXME:XX Move this to ec/lenovo. */ + smi := Create(ctx, "smihandler.c") + defer smi.Close() + + AddSMMFile("smihandler.c", "") + + smi.WriteString( + `/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2014 Vladimir Serbinenko + * + * 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. + */ + +#include <arch/io.h> +#include <console/console.h> +#include <cpu/x86/smm.h> +#include <ec/acpi/ec.h> +#include <ec/lenovo/h8/h8.h> +#include <delay.h> +#include <` + SouthBridge.GetGPIOHeader() + ">\n\n") + + if GPEUnsure { + smi.WriteString("/* FIXME: check this */\n") + } + fmt.Fprintf(smi, "#define GPE_EC_SCI %d\n", GPE) + + smi.WriteString("/* FIXME: check this */\n") + fmt.Fprintf(smi, "#define GPE_EC_WAKE %d\n", wakeGPE) + + smi.WriteString(` +static void mainboard_smm_init(void) +{ + printk(BIOS_DEBUG, "initializing SMI\n"); + /* Enable 0x1600/0x1600 register pair */ + ec_set_bit(0x00, 0x05); +} + +int mainboard_io_trap_handler(int smif) +{ + static int smm_initialized; + + if (!smm_initialized) { + mainboard_smm_init(); + smm_initialized = 1; + } + + return 0; +} + +static void mainboard_smi_handle_ec_sci(void) +{ + u8 status = inb(EC_SC); + u8 event; + + if (!(status & EC_SCI_EVT)) + return; + + event = ec_query(); + printk(BIOS_DEBUG, "EC event %02x\n", event); +} + +void mainboard_smi_gpi(u32 gpi_sts) +{ + if (gpi_sts & (1 << GPE_EC_SCI)) + mainboard_smi_handle_ec_sci(); +} + +int mainboard_smi_apmc(u8 data) +{ + switch (data) { + case APM_CNT_ACPI_ENABLE: + /* use 0x1600/0x1604 to prevent races with userspace */ + ec_set_ports(0x1604, 0x1600); + /* route EC_SCI to SCI */ + gpi_route_interrupt(GPE_EC_SCI, GPI_IS_SCI); + /* discard all events, and enable attention */ + ec_write(0x80, 0x01); + break; + case APM_CNT_ACPI_DISABLE: + /* we have to use port 0x62/0x66, as 0x1600/0x1604 doesn't + provide a EC query function */ + ec_set_ports(0x66, 0x62); + /* route EC_SCI to SMI */ + gpi_route_interrupt(GPE_EC_SCI, GPI_IS_SMI); + /* discard all events, and enable attention */ + ec_write(0x80, 0x01); + break; + default: + break; + } + return 0; +} + +void mainboard_smi_sleep(u8 slp_typ) +{ + if (slp_typ == 3) { + u8 ec_wake = ec_read(0x32); + /* If EC wake events are enabled, enable wake on EC WAKE GPE. */ + if (ec_wake & 0x14) { + /* Redirect EC WAKE GPE to SCI. */ + gpi_route_interrupt(GPE_EC_WAKE, GPI_IS_SCI); + } + } +} +`) + + ec := Create(ctx, "acpi/ec.asl") + defer ec.Close() + + ec.WriteString("#include <ec/lenovo/h8/acpi/ec.asl>\n") + + KconfigBool["EC_LENOVO_PMH7"] = true + KconfigBool["EC_LENOVO_H8"] = true + + pmh := DevTreeNode{ + Chip: "ec/lenovo/pmh7", + Registers: map[string]string{ + "backlight_enable": "0x01", + "dock_event_enable": "0x01", + }, + Children: []DevTreeNode{ + DevTreeNode{ + Chip: "pnp", + Comment: "dummy", + Dev: 0xff, + Func: 1, + }, + }, + } + PutChip("lpc", pmh) + + ecs := ctx.InfoSource.GetEC() + h8 := DevTreeNode{ + Chip: "ec/lenovo/h8", + Children: []DevTreeNode{ + DevTreeNode{ + Chip: "pnp", + Comment: "dummy", + Dev: 0xff, + Func: 2, + IOs: map[uint16]uint16{ + 0x60: 0x62, + 0x62: 0x66, + 0x64: 0x1600, + 0x66: 0x1604, + }, + }, + }, + Comment: "FIXME: has_keyboard_backlight, has_power_management_beeps, has_uwb", + Registers: map[string]string{ + "config0": FormatHex8(ecs[0]), + "config1": FormatHex8(ecs[1]), + "config2": FormatHex8(ecs[2]), + "config3": FormatHex8(ecs[3]), + "beepmask0": FormatHex8(ecs[4]), + "beepmask1": FormatHex8(ecs[5]), + }, + } + for i := 0; i < 0x10; i++ { + if ecs[0x10+i] != 0 { + h8.Registers[fmt.Sprintf("event%x_enable", i)] = FormatHex8(ecs[0x10+i]) + } + } + PutChip("lpc", h8) + + eeprom := DevTreeNode{ + Chip: "drivers/i2c/at24rf08c", + Comment: "eeprom, 8 virtual devices, same chip", + Children: []DevTreeNode{ + DevTreeNode{ + Chip: "i2c", + Dev: 0x54, + }, + DevTreeNode{ + Chip: "i2c", + Dev: 0x55, + }, + DevTreeNode{ + Chip: "i2c", + Dev: 0x56, + }, + DevTreeNode{ + Chip: "i2c", + Dev: 0x57, + }, + DevTreeNode{ + Chip: "i2c", + Dev: 0x5c, + }, + DevTreeNode{ + Chip: "i2c", + Dev: 0x5d, + }, + DevTreeNode{ + Chip: "i2c", + Dev: 0x5e, + }, + DevTreeNode{ + Chip: "i2c", + Dev: 0x5f, + }, + }, + } + PutChip("smbus", eeprom) +} |