mainboard/lenovo: add Lenovo Z61t laptop

This platform shares most hardware components with first-gen Core
Lenovo laptops such as T60/X60, with much smaller EEPROM size as
one of notable differences. The port features Intel graphics,
ATI-based version should work with vendor VBIOS.

Tested peripherals:
 - sleep/resume,
 - USB ports,
 - ACPI Fn key bindings/volume buttons,
 - backlight control,
 - ethernet,
 - wireless (under Linux),
 - sound/beep,
 - dock handling,
 - serial via dock.

Untested peripherals:
 - IrDA,
 - parallel port,
 - PCMCIA,
 - S-Video port,
 - modem,
 - FP reader (should just work),
 - IEEE1394.

Linux 3.16 works with native gfxinit perfectly, with Intel VBIOS
console sometimes displays nothing when i915 framebuffer is used.

Windows 7 has an interrupt assignment issue with iw3945, otherwise
tested stuff is fine.

Change-Id: I84c89cc47d3db126d827f92d50270954bc42f224
Signed-off-by: Andrey Korolyov <andrey@xdel.ru>
Reviewed-on: https://review.coreboot.org/21019
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
This commit is contained in:
Andrey Korolyov 2017-08-16 17:53:40 +02:00 committed by Arthur Heymans
parent 1d2aed2367
commit 60d9ce3937
27 changed files with 1919 additions and 0 deletions

View File

@ -0,0 +1,39 @@
if BOARD_LENOVO_Z61T
config BOARD_SPECIFIC_OPTIONS # dummy
def_bool y
select SYSTEM_TYPE_LAPTOP
select CPU_INTEL_SOCKET_MFCPGA478
select NORTHBRIDGE_INTEL_I945
select NORTHBRIDGE_INTEL_SUBTYPE_I945GM
select SOUTHBRIDGE_INTEL_I82801GX
select SUPERIO_NSC_PC87382
select SUPERIO_NSC_PC87384
select SOUTHBRIDGE_TI_PCI1X2X
select EC_LENOVO_PMH7
select EC_LENOVO_H8
select DRIVERS_I2C_CK505
select HAVE_OPTION_TABLE
select INTEL_INT15
select HAVE_MP_TABLE
select BOARD_ROMSIZE_KB_2048
select CHANNEL_XOR_RANDOMIZATION
select HAVE_ACPI_TABLES
select HAVE_ACPI_RESUME
select MAINBOARD_HAS_NATIVE_VGA_INIT
select H8_DOCK_EARLY_INIT
select HAVE_CMOS_DEFAULT
config MAINBOARD_DIR
string
default lenovo/z61t
config MAINBOARD_PART_NUMBER
string
default "ThinkPad Z61t"
config MAX_CPUS
int
default 2
endif

View File

@ -0,0 +1,2 @@
config BOARD_LENOVO_Z61T
bool "ThinkPad Z61t"

View File

@ -0,0 +1,18 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2007-2008 coresystems GmbH
##
## 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.
##
smm-$(CONFIG_HAVE_SMI_HANDLER) += dock.c
romstage-y += dock.c
romstage-y += gpio.c

View File

@ -0,0 +1,93 @@
/*
* This file is part of the coreboot project.
*
* Copyright (c) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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 "smi.h"
Scope (\_SB)
{
OperationRegion (DLPC, SystemIO, 0x164c, 1)
Field(DLPC, ByteAcc, NoLock, Preserve)
{
, 3,
DSTA, 1,
}
Device(DOCK)
{
Name(_HID, "ACPI0003")
Name(_UID, 0x00)
Name(_PCL, Package() { \_SB } )
Method(_DCK, 1, NotSerialized)
{
if (Arg0) {
Sleep(250)
/* connect dock */
TRAP(SMI_DOCK_CONNECT)
} else {
/* disconnect dock */
TRAP(SMI_DOCK_DISCONNECT)
}
Xor(Arg0, DSTA, Local0)
Return (Local0)
}
Method(_STA, 0, NotSerialized)
{
Return (DSTA)
}
}
}
Scope(\_SB.PCI0.LPCB.EC)
{
OperationRegion(PMH7, SystemIO, 0x15e0, 0x10)
Field(PMH7, ByteAcc, NoLock, Preserve)
{
Offset(0x0c),
PIDX, 8,
Offset(0x0e),
PDAT, 8,
}
IndexField(PIDX, PDAT, ByteAcc, NoLock, Preserve)
{
Offset (0x61),
DPWR, 1,
}
Method(_Q18, 0, NotSerialized)
{
Notify(\_SB.DOCK, 3)
}
Method(_Q37, 0, NotSerialized)
{
if (DPWR) {
Notify(\_SB.DOCK, 0)
} else {
Notify(\_SB.DOCK, 3)
}
}
Method(_Q50, 0, NotSerialized)
{
if (\_SB.DOCK._STA()) {
Notify(\_SB.DOCK, 1)
}
}
}

View File

@ -0,0 +1,17 @@
/*
* This file is part of the coreboot project.
*
* Copyright (c) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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 <ec/lenovo/h8/acpi/ec.asl>

View File

@ -0,0 +1,27 @@
/*
* This file is part of the coreboot project.
*
* Copyright (c) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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 "smi.h"
Scope (\_GPE)
{
Method(_L18, 0, NotSerialized)
{
/* Read EC register to clear wake status */
Store(\_SB.PCI0.LPCB.EC.WAKE, Local0)
/* So that we don't get a warning that Local0 is unused. */
Increment (Local0)
}
}

View File

@ -0,0 +1,58 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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.
*/
/* This is board specific information: IRQ routing for the
* i945
*/
// PCI Interrupt Routing
Method(_PRT)
{
If (PICM) {
Return (Package() {
Package() { 0x0002ffff, 0, 0, 0x10 }, // VGA
Package() { 0x001bffff, 1, 0, 0x11 }, // Audio
Package() { 0x001cffff, 0, 0, 0x14 }, // PCI bridge
Package() { 0x001cffff, 1, 0, 0x15 }, // PCI bridge
Package() { 0x001cffff, 2, 0, 0x16 }, // PCI bridge
Package() { 0x001cffff, 3, 0, 0x17 }, // PCI bridge
Package() { 0x001dffff, 0, 0, 0x10 }, // USB
Package() { 0x001dffff, 1, 0, 0x11 }, // USB
Package() { 0x001dffff, 2, 0, 0x12 }, // USB
Package() { 0x001dffff, 3, 0, 0x13 }, // USB
Package() { 0x001fffff, 0, 0, 0x17 }, // LPC
Package() { 0x001fffff, 1, 0, 0x10 }, // IDE
Package() { 0x001fffff, 2, 0, 0x10 } // SATA
})
} Else {
Return (Package() {
Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, // VGA
Package() { 0x001bffff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, // Audio
Package() { 0x001cffff, 0, \_SB.PCI0.LPCB.LNKE, 0 }, // PCI
Package() { 0x001cffff, 1, \_SB.PCI0.LPCB.LNKF, 0 }, // PCI
Package() { 0x001cffff, 2, \_SB.PCI0.LPCB.LNKG, 0 }, // PCI
Package() { 0x001cffff, 3, \_SB.PCI0.LPCB.LNKH, 0 }, // PCI
Package() { 0x001dffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, // USB
Package() { 0x001dffff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, // USB
Package() { 0x001dffff, 2, \_SB.PCI0.LPCB.LNKC, 0 }, // USB
Package() { 0x001dffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }, // USB
Package() { 0x001fffff, 0, \_SB.PCI0.LPCB.LNKH, 0 }, // LPC
Package() { 0x001fffff, 1, \_SB.PCI0.LPCB.LNKA, 0 }, // IDE
Package() { 0x001fffff, 2, \_SB.PCI0.LPCB.LNKA, 0 } // SATA
})
}
}

View File

@ -0,0 +1,41 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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.
*/
/* This is board specific information: IRQ routing for the
* 0:1e.0 PCI bridge of the ICH7
*/
If (PICM) {
Return (Package() {
Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x10 },
Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x11 },
Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x12 },
Package (0x04) { 0x0001FFFF, 0x00, 0x00, 0x10 },
Package (0x04) { 0x0002FFFF, 0x00, 0x00, 0x15 },
Package (0x04) { 0x0002FFFF, 0x01, 0x00, 0x16 },
Package (0x04) { 0x0008FFFF, 0x00, 0x00, 0x14 }
})
} Else {
Return (Package() {
Package (0x04) { 0x0000FFFF, 0x00, \_SB.PCI0.LPCB.LNKA, 0x00 },
Package (0x04) { 0x0000FFFF, 0x01, \_SB.PCI0.LPCB.LNKB, 0x00 },
Package (0x04) { 0x0000FFFF, 0x02, \_SB.PCI0.LPCB.LNKC, 0x00 },
Package (0x04) { 0x0001FFFF, 0x00, \_SB.PCI0.LPCB.LNKA, 0x00 },
Package (0x04) { 0x0002FFFF, 0x00, \_SB.PCI0.LPCB.LNKF, 0x00 },
Package (0x04) { 0x0002FFFF, 0x01, \_SB.PCI0.LPCB.LNKG, 0x00 },
Package (0x04) { 0x0008FFFF, 0x00, \_SB.PCI0.LPCB.LNKE, 0x00 }
})
}

View File

@ -0,0 +1,81 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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.
*/
/* The _PTS method (Prepare To Sleep) is called before the OS is
* entering a sleep state. The sleep state number is passed in Arg0
*/
Method(_PTS,1)
{
\_SB.PCI0.LPCB.EC.MUTE(1)
\_SB.PCI0.LPCB.EC.USBP(0)
\_SB.PCI0.LPCB.EC.RADI(0)
}
/* The _WAK method is called on system wakeup */
Method(_WAK,1)
{
// CPU specific part
// Notify PCI Express slots in case a card
// was inserted while a sleep state was active.
// Are we going to S3?
If (LEqual(Arg0, 3)) {
// ..
}
// Are we going to S4?
If (LEqual(Arg0, 4)) {
// ..
}
// TODO: Windows XP SP2 P-State restore
Return(Package(){0,0})
}
/* System Bus */
Scope(\_SB)
{
/* This method is placed on the top level, so we can make sure it's the
* first executed _INI method.
*/
Method(_INI, 0)
{
/* The DTS data in NVS is probably not up to date.
* Update temperature values and make sure AP thermal
* interrupts can happen
*/
// TRAP(71) // TODO
\GOS()
/* And the OS workarounds start right after we know what we're
* running: Windows XP SP1 needs to have C-State coordination
* enabled in SMM.
*/
If (LAnd(LEqual(OSYS, 2001), MPEN)) {
// TRAP(61) // TODO
}
/* SMM power state and C4-on-C3 settings need to be updated */
// TRAP(43) // TODO
}
}

View File

@ -0,0 +1,32 @@
/*
* This file is part of the coreboot project.
*
* Copyright (c) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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 "smi.h"
Scope (\)
{
Method(BRTD, 0, NotSerialized)
{
Trap(SMI_BRIGHTNESS_DOWN)
\_SB.PCI0.GFX0.DECB()
}
Method(BRTU, 0, NotSerialized)
{
Trap(SMI_BRIGHTNESS_UP)
\_SB.PCI0.GFX0.INCB()
}
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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 <string.h>
#include <console/console.h>
#include <arch/io.h>
#include <arch/ioapic.h>
#include <arch/acpi.h>
#include <arch/acpigen.h>
#include <arch/smp/mpspec.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include "southbridge/intel/i82801gx/nvs.h"
void acpi_create_gnvs(global_nvs_t *gnvs)
{
/* Enable both COM ports */
gnvs->cmap = 0x01;
gnvs->cmbp = 0x01;
}

View File

@ -0,0 +1,7 @@
Board name: Z61t
Category: laptop
ROM package: SOIC-8
ROM protocol: SPI
ROM socketed: n
Flashrom support: n
Release year: 2006

View File

@ -0,0 +1,19 @@
boot_option=Fallback
debug_level=Spew
hyper_threading=Enable
nmi=Enable
boot_devices=''
boot_default=0x41
cmos_defaults_loaded=Yes
lpt=Enable
touchpad=Enable
volume=0x3
first_battery=Primary
bluetooth=Enable
wlan=Enable
wwan=Enable
trackpoint=Enable
sticky_fn=Disable
power_management_beeps=Enable
low_battery_beep=Enable
gfx_uma_size=8M

View File

@ -0,0 +1,136 @@
#
# This file is part of the coreboot project.
#
# Copyright (C) 2007-2008 coresystems GmbH
#
# 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.
#
# -----------------------------------------------------------------
entries
# -----------------------------------------------------------------
# Status Register A
# -----------------------------------------------------------------
# Status Register B
# -----------------------------------------------------------------
# Status Register C
#96 4 r 0 status_c_rsvd
#100 1 r 0 uf_flag
#101 1 r 0 af_flag
#102 1 r 0 pf_flag
#103 1 r 0 irqf_flag
# -----------------------------------------------------------------
# Status Register D
#104 7 r 0 status_d_rsvd
#111 1 r 0 valid_cmos_ram
# -----------------------------------------------------------------
# Diagnostic Status Register
#112 8 r 0 diag_rsvd1
# -----------------------------------------------------------------
0 120 r 0 reserved_memory
#120 264 r 0 unused
# -----------------------------------------------------------------
# RTC_BOOT_BYTE (coreboot hardcoded)
384 1 e 4 boot_option
388 4 h 0 reboot_counter
#390 2 r 0 unused?
# -----------------------------------------------------------------
# coreboot config options: console
395 4 e 6 debug_level
#399 1 r 0 unused
#400 8 r 0 reserved for century byte
# coreboot config options: southbridge
408 1 e 1 nmi
#409 2 e 7 power_on_after_fail
# coreboot config options: northbridge
411 3 e 11 gfx_uma_size
# coreboot config options: bootloader
416 512 s 0 boot_devices
928 8 h 0 boot_default
936 1 e 8 cmos_defaults_loaded
937 1 e 1 lpt
#938 7 r 0 unused
# coreboot config options: cpu
944 1 e 2 hyper_threading
#945 3 r 0 unused
# coreboot config options: ec
948 1 e 1 touchpad
949 1 e 1 bluetooth
950 1 e 1 wwan
951 1 e 1 wlan
952 8 h 0 volume
960 1 e 9 first_battery
961 1 e 1 trackpoint
962 1 e 1 fn_ctrl_swap
963 1 e 1 sticky_fn
964 1 e 1 power_management_beeps
965 1 e 1 low_battery_beep
# coreboot config options: check sums
984 16 h 0 check_sum
#1000 24 r 0 amd_reserved
# RAM initialization internal data
1024 8 r 0 C0WL0REOST
1032 8 r 0 C1WL0REOST
1040 8 r 0 RCVENMT
1048 4 r 0 C0DRT1
1052 4 r 0 C1DRT1
# -----------------------------------------------------------------
enumerations
#ID value text
1 0 Disable
1 1 Enable
2 0 Enable
2 1 Disable
4 0 Fallback
4 1 Normal
6 1 Emergency
6 2 Alert
6 3 Critical
6 4 Error
6 5 Warning
6 6 Notice
6 7 Info
6 8 Debug
6 9 Spew
7 0 Disable
7 1 Enable
7 2 Keep
8 0 No
8 1 Yes
9 0 Secondary
9 1 Primary
11 0 1M
11 1 4M
11 2 8M
11 3 16M
11 4 32M
11 5 48M
11 6 64M
# -----------------------------------------------------------------
checksums
checksum 392 983 984

View File

@ -0,0 +1,239 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2007-2009 coresystems GmbH
## Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
##
## 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.
##
chip northbridge/intel/i945
# IGD Displays
register "gfx.ndid" = "3"
register "gfx.did" = "{ 0x80000100, 0x80000240, 0x80000410, 0x80000410, 0x00000005 }"
register "gpu_hotplug" = "0x00000220"
register "gpu_lvds_use_spread_spectrum_clock" = "1"
register "pwm_freq" = "275"
register "gpu_panel_power_up_delay" = "250"
register "gpu_panel_power_backlight_on_delay" = "2380"
register "gpu_panel_power_down_delay" = "250"
register "gpu_panel_power_backlight_off_delay" = "2380"
register "gpu_panel_power_cycle_delay" = "2"
device cpu_cluster 0 on
chip cpu/intel/socket_mFCPGA478
device lapic 0 on end
end
end
register "pci_mmio_size" = "768"
device domain 0 on
device pci 00.0 on # Host bridge
subsystemid 0x17aa 0x2017
end
device pci 01.0 on # PEG
device pci 00.0 on end # VGA
end
device pci 02.0 on # GMA Graphics controller
subsystemid 0x17aa 0x201a
end
device pci 02.1 on # display controller
subsystemid 0x17aa 0x201a
end
chip southbridge/intel/i82801gx
register "pirqa_routing" = "0x0b"
register "pirqb_routing" = "0x0b"
register "pirqc_routing" = "0x0b"
register "pirqd_routing" = "0x0b"
register "pirqe_routing" = "0x0b"
register "pirqf_routing" = "0x0b"
register "pirqg_routing" = "0x0b"
register "pirqh_routing" = "0x0b"
# GPI routing
# 0 No effect (default)
# 1 SMI# (if corresponding ALT_GPI_SMI_EN bit is also set)
# 2 SCI (if corresponding GPIO_EN bit is also set)
register "gpi13_routing" = "2"
register "gpi12_routing" = "2"
register "gpi8_routing" = "2"
register "sata_ahci" = "0x1"
register "sata_ports_implemented" = "0x01"
register "gpe0_en" = "0x11000006"
register "alt_gp_smi_en" = "0x1000"
register "c4onc3_enable" = "1"
register "c3_latency" = "0x23"
register "docking_supported" = "1"
register "p_cnt_throttling_supported" = "1"
device pci 1b.0 on # Audio Controller
subsystemid 0x17aa 0x2010
end
device pci 1c.0 on # PCI Express Port 1
subsystemid 0x17aa 0x2011
end
device pci 1c.1 on # PCI Express Port 2
subsystemid 0x17aa 0x2011
end
device pci 1c.2 on # PCI Express Port 3
subsystemid 0x17aa 0x2011
end
device pci 1c.3 on # PCI Express Port 4
subsystemid 0x17aa 0x2011
end
device pci 1d.0 on # USB UHCI
subsystemid 0x17aa 0x200a
end
device pci 1d.1 on # USB UHCI
subsystemid 0x17aa 0x200a
end
device pci 1d.2 on # USB UHCI
subsystemid 0x17aa 0x200a
end
device pci 1d.3 on # USB UHCI
subsystemid 0x17aa 0x200a
end
device pci 1d.7 on # USB2 EHCI
subsystemid 0x17aa 0x200b
end
device pci 1e.0 on # PCI Bridge
chip southbridge/ti/pci1x2x
device pci 00.0 on
subsystemid 0x17aa 0x2013
end
register "scr" = "0x0844d070"
register "mrr" = "0x01d01002"
end
end
device pci 1f.0 on # PCI-LPC bridge
subsystemid 0x17aa 0x2009
chip ec/lenovo/pmh7
device pnp ff.1 on # dummy
end
register "backlight_enable" = "0x01"
register "dock_event_enable" = "0x01"
end
chip ec/lenovo/h8
device pnp ff.2 on # dummy
io 0x60 = 0x62
io 0x62 = 0x66
io 0x64 = 0x1600
io 0x66 = 0x1604
end
register "config0" = "0xa6"
register "config1" = "0x05"
register "config2" = "0xa0"
register "config3" = "0x01"
register "beepmask0" = "0xfe"
register "beepmask1" = "0x96"
register "has_power_management_beeps" = "1"
register "event2_enable" = "0xff"
register "event3_enable" = "0xff"
register "event4_enable" = "0xf4"
register "event5_enable" = "0x3f"
register "event6_enable" = "0x80"
register "event7_enable" = "0x01"
register "event8_enable" = "0x01"
register "event9_enable" = "0xff"
register "eventa_enable" = "0xff"
register "eventb_enable" = "0xff"
register "eventc_enable" = "0x3c"
register "eventd_enable" = "0xff"
end
chip superio/nsc/pc87382
device pnp 164e.2 on # IR
io 0x60 = 0x2f8
end
device pnp 164e.3 off # Serial Port
io 0x60 = 0x3f8
end
device pnp 164e.7 on # GPIO
io 0x60 = 0x1680
end
device pnp 164e.19 on # DLPC
io 0x60 = 0x164c
end
end
chip superio/nsc/pc87384
device pnp 2e.0 off #FDC
end
device pnp 2e.1 on # Parallel Port
io 0x60 = 0x3bc
irq 0x70 = 7
end
device pnp 2e.2 off # Serial Port / IR
io 0x60 = 0x2f8
irq 0x70 = 3
end
device pnp 2e.3 on # Serial Port
io 0x60 = 0x3f8
irq 0x70 = 4
end
device pnp 2e.7 on # GPIO
io 0x60 = 0x1620
end
device pnp 2e.a off # WDT
end
end
end
device pci 1f.2 on # SATA
subsystemid 0x17aa 0x200d
end
device pci 1f.3 on # SMBUS
subsystemid 0x17aa 0x200f
chip drivers/i2c/ck505
register "mask" = "{ 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff }"
# vendor clockgen setup
register "regs" = "{ 0x6d, 0xff, 0xff,
0x20, 0x41, 0x7f, 0x18, 0x00 }"
device i2c 69 on end
end
# eeprom, 8 virtual devices, same chip
chip drivers/i2c/at24rf08c
device i2c 54 on end
device i2c 55 on end
device i2c 56 on end
device i2c 57 on end
device i2c 5c on end
device i2c 5d on end
device i2c 5e on end
device i2c 5f on end
end
end
end
end
end

View File

@ -0,0 +1,233 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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 <console/console.h>
#include <device/device.h>
#include <arch/io.h>
#include <delay.h>
#include "dock.h"
#include <superio/nsc/pc87384/pc87384.h>
#include "ec/acpi/ec.h"
#include "ec/lenovo/pmh7/pmh7.h"
#include "southbridge/intel/i82801gx/i82801gx.h"
#define DLPC_CONTROL 0x164c
static void dlpc_write_register(int reg, int value)
{
outb(reg, 0x164e);
outb(value, 0x164f);
}
static u8 dlpc_read_register(int reg)
{
outb(reg, 0x164e);
return inb(0x164f);
}
static void dock_write_register(int reg, int value)
{
outb(reg, 0x2e);
outb(value, 0x2f);
}
static u8 dock_read_register(int reg)
{
outb(reg, 0x2e);
return inb(0x2f);
}
static void dlpc_gpio_set_mode(int port, int mode)
{
dlpc_write_register(0xf0, port);
dlpc_write_register(0xf1, mode);
}
static void dock_gpio_set_mode(int port, int mode, int irq)
{
dock_write_register(0xf0, port);
dock_write_register(0xf1, mode);
dock_write_register(0xf2, irq);
}
static void dlpc_gpio_init(void)
{
/* Select GPIO module */
dlpc_write_register(0x07, 0x07);
/* GPIO Base Address 0x1680 */
dlpc_write_register(0x60, 0x16);
dlpc_write_register(0x61, 0x80);
/* Activate GPIO */
dlpc_write_register(0x30, 0x01);
dlpc_gpio_set_mode(0x00, 3);
dlpc_gpio_set_mode(0x01, 3);
dlpc_gpio_set_mode(0x02, 0);
dlpc_gpio_set_mode(0x03, 3);
dlpc_gpio_set_mode(0x04, 4);
dlpc_gpio_set_mode(0x20, 4);
dlpc_gpio_set_mode(0x21, 4);
dlpc_gpio_set_mode(0x23, 4);
}
int dlpc_init(void)
{
int timeout = 1000;
/* Enable 14.318MHz CLK on CLKIN */
dlpc_write_register(0x29, 0xa0);
while(!(dlpc_read_register(0x29) & 0x10) && timeout--)
udelay(1000);
if (!timeout)
return 1;
/* Select DLPC module */
dlpc_write_register(0x07, 0x19);
/* DLPC Base Address */
dlpc_write_register(0x60, (DLPC_CONTROL >> 8) & 0xff);
dlpc_write_register(0x61, DLPC_CONTROL & 0xff);
/* Activate DLPC */
dlpc_write_register(0x30, 0x01);
/* Reset docking state */
outb(0x00, DLPC_CONTROL);
dlpc_gpio_init();
return 0;
}
static int dock_superio_init(void)
{
int timeout = 1000;
/* startup 14.318MHz Clock */
dock_write_register(0x29, 0xa0);
/* wait until clock is settled */
while(!(dock_read_register(0x29) & 0x10) && timeout--)
udelay(1000);
if (!timeout)
return 1;
/* set GPIO pins to Serial/Parallel Port
* functions
*/
dock_write_register(0x22, 0xa9);
/* enable serial port */
dock_write_register(0x07, PC87384_SP1);
dock_write_register(0x30, 0x01);
dock_write_register(0x07, PC87384_GPIO);
dock_write_register(0x60, 0x16);
dock_write_register(0x61, 0x20);
/* enable GPIO */
dock_write_register(0x30, 0x01);
dock_gpio_set_mode(0x00, PC87384_GPIO_PIN_DEBOUNCE |
PC87384_GPIO_PIN_PULLUP, 0x00);
dock_gpio_set_mode(0x01, PC87384_GPIO_PIN_TYPE_PUSH_PULL |
PC87384_GPIO_PIN_OE, 0x00);
dock_gpio_set_mode(0x02, PC87384_GPIO_PIN_TYPE_PUSH_PULL |
PC87384_GPIO_PIN_OE, 0x00);
dock_gpio_set_mode(0x03, PC87384_GPIO_PIN_DEBOUNCE |
PC87384_GPIO_PIN_PULLUP, 0x00);
dock_gpio_set_mode(0x04, PC87384_GPIO_PIN_DEBOUNCE |
PC87384_GPIO_PIN_PULLUP, 0x00);
dock_gpio_set_mode(0x05, PC87384_GPIO_PIN_DEBOUNCE |
PC87384_GPIO_PIN_PULLUP, 0x00);
dock_gpio_set_mode(0x06, PC87384_GPIO_PIN_DEBOUNCE |
PC87384_GPIO_PIN_PULLUP, 0x00);
dock_gpio_set_mode(0x07, PC87384_GPIO_PIN_DEBOUNCE |
PC87384_GPIO_PIN_PULLUP, 0x00);
/* no GPIO events enabled for PORT0 */
outb(0x00, 0x1622);
/* clear GPIO events on PORT0 */
outb(0xff, 0x1623);
outb(0xff, 0x1624);
/* no GPIO events enabled for PORT1 */
outb(0x00, 0x1626);
/* clear GPIO events on PORT1*/
outb(0xff, 0x1627);
outb(0x1F, 0x1628);
outb(0xfd, 0x1620);
return 0;
}
int dock_connect(void)
{
int timeout = 1000;
outb(0x07, DLPC_CONTROL);
timeout = 1000;
while(!(inb(DLPC_CONTROL) & 8) && timeout--)
udelay(1000);
if (!timeout) {
/* docking failed, disable DLPC switch */
outb(0x00, DLPC_CONTROL);
dlpc_write_register(0x30, 0x00);
return 1;
}
/* Assert D_PLTRST# */
outb(0xfe, 0x1680);
udelay(1000);
/* Deassert D_PLTRST# */
outb(0xff, 0x1680);
udelay(10000);
return dock_superio_init();
}
void dock_disconnect(void)
{
/* disconnect LPC bus */
outb(0x00, DLPC_CONTROL);
/* Assert PLTRST and DLPCPD */
outb(0xfc, 0x1680);
}
int dock_present(void)
{
return pmh7_register_read(0x61) & 1;
}
int legacy_io_present(void)
{
return !(inb(DEFAULT_GPIOBASE + 0x0c) & 0x40);
}
void legacy_io_init(void)
{
/* Enable Power for Ultrabay slot */
pmh7_ultrabay_power_enable(1);
udelay(100000);
dock_superio_init();
}

View File

@ -0,0 +1,26 @@
/*
* This file is part of the coreboot project.
*
* Copyright (c) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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 THINKPAD_X60_DOCK_H
#define THINKPAD_X60_DOCK_H
int dock_connect(void);
void dock_disconnect(void);
int dock_present(void);
int dlpc_init(void);
int legacy_io_present(void);
void legacy_io_init(void);
#endif

View File

@ -0,0 +1,65 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
*
* 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.
*/
#define THINKPAD_EC_GPE 28
#define BRIGHTNESS_UP \BRTU
#define BRIGHTNESS_DOWN \BRTD
#define ACPI_VIDEO_DEVICE \_SB.PCI0.GFX0
DefinitionBlock(
"dsdt.aml",
"DSDT",
0x03, // DSDT revision: ACPI v3.0
"COREv4", // OEM id
"COREBOOT", // OEM table id
0x20090419 // OEM revision
)
{
// Some generic macros
#include "acpi/platform.asl"
// global NVS and variables
#include <southbridge/intel/i82801gx/acpi/globalnvs.asl>
#include <southbridge/intel/common/acpi/platform.asl>
// General Purpose Events
#include "acpi/gpe.asl"
// mainboard specific devices
#include "acpi/mainboard.asl"
Scope (\)
{
// backlight control, display switching, lid
#include "acpi/video.asl"
}
#include <cpu/intel/common/acpi/cpu.asl>
Scope (\_SB) {
Device (PCI0)
{
#include <northbridge/intel/i945/acpi/i945.asl>
#include <southbridge/intel/i82801gx/acpi/ich7.asl>
}
}
/* Chipset specific sleep states */
#include <southbridge/intel/i82801gx/acpi/sleepstates.asl>
// Dock support code
#include "acpi/dock.asl"
}

View File

@ -0,0 +1,112 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2016 Arthur Heymans <arthur@aheymans.xyz>
*
* 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 <southbridge/intel/common/gpio.h>
static const struct pch_gpio_set1 pch_gpio_set1_mode = {
.gpio1 = GPIO_MODE_GPIO,
.gpio6 = GPIO_MODE_GPIO, /* LEGACYIO# */
.gpio7 = GPIO_MODE_GPIO, /* BDC_PRESENCE# */
.gpio8 = GPIO_MODE_GPIO, /* H8_WAKE# */
.gpio9 = GPIO_MODE_GPIO,
.gpio10 = GPIO_MODE_GPIO, /* MDI_DETECT */
.gpio12 = GPIO_MODE_GPIO, /* H8SCI# */
.gpio13 = GPIO_MODE_GPIO,
.gpio14 = GPIO_MODE_GPIO, /* CPUSB# */
.gpio15 = GPIO_MODE_GPIO, /* CPPE# */
.gpio19 = GPIO_MODE_GPIO,
.gpio22 = GPIO_MODE_GPIO,
.gpio24 = GPIO_MODE_GPIO,
.gpio25 = GPIO_MODE_GPIO, /* MDC_KILL# */
.gpio26 = GPIO_MODE_GPIO,
.gpio27 = GPIO_MODE_GPIO, /* EXC_PWR_CTRL */
.gpio28 = GPIO_MODE_GPIO, /* EXC_AUX_CTRL */
};
static const struct pch_gpio_set1 pch_gpio_set1_direction = {
.gpio1 = GPIO_DIR_INPUT,
.gpio6 = GPIO_DIR_INPUT,
.gpio7 = GPIO_DIR_INPUT,
.gpio8 = GPIO_DIR_INPUT,
.gpio9 = GPIO_DIR_INPUT,
.gpio10 = GPIO_DIR_INPUT,
.gpio12 = GPIO_DIR_INPUT,
.gpio13 = GPIO_DIR_INPUT,
.gpio14 = GPIO_DIR_INPUT,
.gpio15 = GPIO_DIR_INPUT,
.gpio19 = GPIO_DIR_OUTPUT,
.gpio22 = GPIO_DIR_INPUT,
.gpio24 = GPIO_DIR_OUTPUT,
.gpio25 = GPIO_DIR_OUTPUT,
.gpio26 = GPIO_DIR_OUTPUT,
.gpio27 = GPIO_DIR_OUTPUT,
.gpio28 = GPIO_DIR_OUTPUT,
};
static const struct pch_gpio_set1 pch_gpio_set1_level = {
.gpio19 = GPIO_LEVEL_HIGH,
.gpio24 = GPIO_LEVEL_HIGH,
.gpio25 = GPIO_LEVEL_HIGH,
.gpio26 = GPIO_LEVEL_LOW,
.gpio27 = GPIO_LEVEL_HIGH,
.gpio28 = GPIO_LEVEL_HIGH,
};
static const struct pch_gpio_set1 pch_gpio_set1_invert = {
.gpio1 = GPIO_INVERT,
.gpio6 = GPIO_INVERT,
.gpio7 = GPIO_INVERT,
.gpio8 = GPIO_INVERT,
.gpio12 = GPIO_INVERT,
.gpio13 = GPIO_INVERT,
};
static const struct pch_gpio_set1 pch_gpio_set1_blink = {
};
static const struct pch_gpio_set2 pch_gpio_set2_mode = {
.gpio36 = GPIO_MODE_GPIO, /*PLANARID0 */
.gpio37 = GPIO_MODE_GPIO, /*PLANARID1 */
.gpio38 = GPIO_MODE_GPIO, /*PLANARID2 */
.gpio39 = GPIO_MODE_GPIO, /*PLANARID3 */
.gpio48 = GPIO_MODE_GPIO,
};
static const struct pch_gpio_set2 pch_gpio_set2_direction = {
.gpio36 = GPIO_DIR_INPUT,
.gpio37 = GPIO_DIR_INPUT,
.gpio38 = GPIO_DIR_INPUT,
.gpio39 = GPIO_DIR_INPUT,
.gpio48 = GPIO_DIR_OUTPUT,
};
static const struct pch_gpio_set2 pch_gpio_set2_level = {
.gpio48 = GPIO_LEVEL_HIGH,
};
const struct pch_gpio_map mainboard_gpio_map = {
.set1 = {
.mode = &pch_gpio_set1_mode,
.direction = &pch_gpio_set1_direction,
.level = &pch_gpio_set1_level,
.blink = &pch_gpio_set1_blink,
.invert = &pch_gpio_set1_invert,
},
.set2 = {
.mode = &pch_gpio_set2_mode,
.direction = &pch_gpio_set2_direction,
.level = &pch_gpio_set2_level,
},
};

View File

@ -0,0 +1,38 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
* 2012 secunet Security Networks AG
*
* 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 <device/azalia_device.h>
const u32 cim_verb_data[] = {
0x11d41981, /* Codec Vendor / Device ID: Analog Devices AD1981 */
0x17aa2025, /* Subsystem ID */
0x0000000b, /* Number of 4 dword sets */
AZALIA_SUBVENDOR(0x0, 0x17aa2025),
AZALIA_PIN_CFG(0, 0x05, 0xc3014110),
AZALIA_PIN_CFG(0, 0x06, 0x4221401f),
AZALIA_PIN_CFG(0, 0x07, 0x591311f0),
AZALIA_PIN_CFG(0, 0x08, 0xc3a15020),
AZALIA_PIN_CFG(0, 0x09, 0x41813021),
AZALIA_PIN_CFG(0, 0x0a, 0x014470f0),
AZALIA_PIN_CFG(0, 0x16, 0x59f311f0),
AZALIA_PIN_CFG(0, 0x17, 0x59931122),
AZALIA_PIN_CFG(0, 0x18, 0x41a19023),
AZALIA_PIN_CFG(0, 0x19, 0x9933e12e)
};
const u32 pc_beep_verbs[0] = {};
AZALIA_ARRAY_SIZES;

View File

@ -0,0 +1,84 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
* Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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 <device/pci_def.h>
#include <device/device.h>
#include <ec/lenovo/pmh7/pmh7.h>
#include <ec/lenovo/h8/h8.h>
#include <ec/acpi/ec.h>
#include <northbridge/intel/i945/i945.h>
#include <pc80/mc146818rtc.h>
#include <drivers/intel/gma/int15.h>
#include <arch/acpigen.h>
#define PANEL INT15_5F35_CL_DISPLAY_DEFAULT
static acpi_cstate_t cst_entries[] = {
{ 1, 1, 1000, { 0x7f, 1, 2, { 0 }, 1, 0 } },
{ 2, 1, 500, { 0x01, 8, 0, { 0 }, DEFAULT_PMBASE + LV2, 0 } },
{ 3, 17, 250, { 0x01, 8, 0, { 0 }, DEFAULT_PMBASE + LV3, 0 } },
};
int get_cst_entries(acpi_cstate_t **entries)
{
*entries = cst_entries;
return ARRAY_SIZE(cst_entries);
}
static void mainboard_init(device_t dev)
{
struct southbridge_intel_i82801gx_config *config;
device_t idedev;
install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_INT_LVDS,
GMA_INT15_PANEL_FIT_DEFAULT,
PANEL, 3);
/* If we're resuming from suspend, blink suspend LED */
if (acpi_is_wakeup_s3())
ec_write(0x0c, 0xc7);
idedev = dev_find_slot(0, PCI_DEVFN(0x1f,1));
if (!(inb(DEFAULT_GPIOBASE + 0x0c) & 0x40)) {
/* legacy I/O connected */
pmh7_ultrabay_power_enable(1);
ec_write(0x0c, 0x84);
} else if (idedev && idedev->chip_info &&
h8_ultrabay_device_present()) {
config = idedev->chip_info;
config->ide_enable_primary = 1;
pmh7_ultrabay_power_enable(1);
ec_write(0x0c, 0x84);
} else {
pmh7_ultrabay_power_enable(0);
ec_write(0x0c, 0x04);
}
/* set dock status led */
ec_write(0x0c, 0x08);
ec_write(0x0c, inb(0x164c) & 8 ? 0x89 : 0x09);
}
static void mainboard_enable(device_t dev)
{
dev->ops->init = mainboard_init;
}
struct chip_operations mainboard_ops = {
.enable_dev = mainboard_enable,
};

View File

@ -0,0 +1,71 @@
/*
* This file is part of the coreboot project.
*
* Copyright (c) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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 <device/device.h>
#include <device/pci.h>
#include <console/console.h>
#include <arch/smp/mpspec.h>
#include <arch/ioapic.h>
#include <string.h>
#include <stdint.h>
static void *smp_write_config_table(void *v)
{
struct mp_config_table *mc;
int isa_bus;
mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
mptable_init(mc, LOCAL_APIC_ADDR);
smp_write_processors(mc);
mptable_write_buses(mc, NULL, &isa_bus);
/* I/O APICs: APIC ID Version State Address */
smp_write_ioapic(mc, 2, 0x20, VIO_APIC_VADDR);
/* Legacy Interrupts */
mptable_add_isa_interrupts(mc, isa_bus, 0x2, 0);
smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, isa_bus, 0x00, MP_APIC_ALL, 0x00);
smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, isa_bus, 0x00, MP_APIC_ALL, 0x01);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x01 << 2), 0x02, 0x10); /* PCIe root 0.02.0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x02 << 2), 0x02, 0x10); /* VGA 0.02.0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1b << 2), 0x02, 0x11); /* HD Audio 0:1b.0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1c << 2), 0x02, 0x14); /* PCIe 0:1c.0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1c << 2) | 0x01, 0x02, 0x15); /* PCIe 0:1c.1 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1c << 2) | 0x02, 0x02, 0x16); /* PCIe 0:1c.2 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1c << 2) | 0x03, 0x02, 0x17); /* PCIe 0:1c.3 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1d << 2) , 0x02, 0x10); /* USB 0:1d.0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1d << 2) | 0x01, 0x02, 0x11); /* USB 0:1d.1 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1d << 2) | 0x02, 0x02, 0x12); /* USB 0:1d.2 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1d << 2) | 0x03, 0x02, 0x13); /* USB 0:1d.3 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1f << 2) , 0x02, 0x17); /* LPC 0:1f.0 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1f << 2) | 0x01, 0x02, 0x10); /* IDE 0:1f.1 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x00, (0x1f << 2) | 0x02, 0x02, 0x10); /* SATA 0:1f.2 */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x06, (0x00 << 2) | 0x00, 0x02, 0x10); /* Cardbus 6:00.0 */
mptable_lintsrc(mc, isa_bus);
return mptable_finalize(mc);
}
unsigned long write_smp_table(unsigned long addr)
{
void *v;
v = smp_write_floating_table(addr, 0);
return (unsigned long)smp_write_config_table(v);
}

View File

@ -0,0 +1,246 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 coresystems GmbH
* Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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.
*/
// __PRE_RAM__ means: use "unsigned" for device, not a struct.
#include <stdint.h>
#include <string.h>
#include <arch/io.h>
#include <device/pci_def.h>
#include <device/pnp_def.h>
#include <cpu/x86/lapic.h>
#include <lib.h>
#include <arch/acpi.h>
#include <cbmem.h>
#include <timestamp.h>
#include <pc80/mc146818rtc.h>
#include <console/console.h>
#include <cpu/x86/bist.h>
#include <cpu/intel/romstage.h>
#include <halt.h>
#include <northbridge/intel/i945/i945.h>
#include <northbridge/intel/i945/raminit.h>
#include <southbridge/intel/i82801gx/i82801gx.h>
#include <southbridge/intel/common/gpio.h>
#include "dock.h"
static void ich7_enable_lpc(void)
{
// Enable Serial IRQ
pci_write_config8(PCI_DEV(0, 0x1f, 0), SERIRQ_CNTL, 0xd0);
// decode range
pci_write_config16(PCI_DEV(0, 0x1f, 0), LPC_IO_DEC, 0x0210);
// decode range
pci_write_config16(PCI_DEV(0, 0x1f, 0), LPC_EN, 0x1f0d);
/* range 0x1600 - 0x167f */
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x84, 0x1601);
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x86, 0x007c);
/* range 0x15e0 - 0x10ef */
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x88, 0x15e1);
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x8a, 0x000c);
/* range 0x1680 - 0x169f */
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x8c, 0x1681);
pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x8e, 0x001c);
}
static void early_superio_config(void)
{
int timeout = 100000;
pnp_devfn_t dev = PNP_DEV(0x2e, 3);
pnp_write_config(dev, 0x29, 0xa0);
while(!(pnp_read_config(dev, 0x29) & 0x10) && timeout--)
udelay(1000);
/* Enable COM1 */
pnp_set_logical_device(dev);
pnp_set_iobase(dev, PNP_IDX_IO0, 0x3f8);
pnp_set_enable(dev, 1);
}
static void rcba_config(void)
{
/* Set up virtual channel 0 */
RCBA32(V0CTL) = 0x80000001;
RCBA32(V1CAP) = 0x03128010;
/* Device 1f interrupt pin register */
RCBA32(D31IP) = 0x00001230;
RCBA32(D29IP) = 0x40004321;
/* PCIe Interrupts */
RCBA32(D28IP) = 0x00004321;
/* HD Audio Interrupt */
RCBA32(D27IP) = 0x00000002;
/* dev irq route register */
RCBA16(D31IR) = 0x1007;
RCBA16(D30IR) = 0x0076;
RCBA16(D29IR) = 0x3210;
RCBA16(D28IR) = 0x7654;
RCBA16(D27IR) = 0x0010;
/* Enable IOAPIC */
RCBA8(OIC) = 0x03;
/* Disable unused devices */
RCBA32(FD) = FD_PCIE6 | FD_PCIE5 | FD_INTLAN | FD_ACMOD | FD_ACAUD | FD_PATA;
RCBA32(FD) |= (1 << 0); // Required.
/* Set up I/O Trap #0 for 0xfe00 (SMIC) */
RCBA32(0x1e84) = 0x00020001;
RCBA32(IOTR0) = 0x0000fe01;
/* Set up I/O Trap #3 for 0x800-0x80c (Trap) */
RCBA32(0x1e9c) = 0x000200f0;
RCBA32(IOTR3) = 0x000c0801;
}
static void early_ich7_init(void)
{
uint8_t reg8;
uint32_t reg32;
// program secondary mlt XXX byte?
pci_write_config8(PCI_DEV(0, 0x1e, 0), 0x1b, 0x20);
// reset rtc power status
reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa4);
reg8 &= ~(1 << 2);
pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa4, reg8);
// usb transient disconnect
reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xad);
reg8 |= (3 << 0);
pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xad, reg8);
reg32 = pci_read_config32(PCI_DEV(0, 0x1d, 7), 0xfc);
reg32 |= (1 << 29) | (1 << 17);
pci_write_config32(PCI_DEV(0, 0x1d, 7), 0xfc, reg32);
reg32 = pci_read_config32(PCI_DEV(0, 0x1d, 7), 0xdc);
reg32 |= (1 << 31) | (1 << 27);
pci_write_config32(PCI_DEV(0, 0x1d, 7), 0xdc, reg32);
RCBA32(0x0088) = 0x0011d000;
RCBA16(0x01fc) = 0x060f;
RCBA32(0x01f4) = 0x86000040;
RCBA32(0x0214) = 0x10030549;
RCBA32(0x0218) = 0x00020504;
RCBA8(0x0220) = 0xc5;
reg32 = RCBA32(0x3410);
reg32 |= (1 << 6);
RCBA32(GCS) = reg32;
reg32 = RCBA32(0x3430);
reg32 &= ~(3 << 0);
reg32 |= (1 << 0);
RCBA32(0x3430) = reg32;
RCBA32(FD) |= (1 << 0);
RCBA16(0x0200) = 0x2008;
RCBA8(0x2027) = 0x0d;
RCBA16(0x3e08) |= (1 << 7);
RCBA16(0x3e48) |= (1 << 7);
RCBA32(0x3e0e) |= (1 << 7);
RCBA32(0x3e4e) |= (1 << 7);
// next step only on ich7m b0 and later:
reg32 = RCBA32(0x2034);
reg32 &= ~(0x0f << 16);
reg32 |= (5 << 16);
RCBA32(0x2034) = reg32;
}
void mainboard_romstage_entry(unsigned long bist)
{
int s3resume = 0;
int dock_err;
const u8 spd_addrmap[2 * DIMM_SOCKETS] = { 0x50, 0, 0x51, 0 };
timestamp_init(get_initial_timestamp());
timestamp_add_now(TS_START_ROMSTAGE);
if (bist == 0)
enable_lapic();
ich7_enable_lpc();
/* We want early GPIO setup, to be able to detect legacy I/O module */
pci_write_config32(PCI_DEV(0, 0x1f, 0), GPIOBASE, DEFAULT_GPIOBASE | 1);
/* Enable GPIOs */
pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x4c /* GC */ , 0x10);
setup_pch_gpios(&mainboard_gpio_map);
dock_err = dlpc_init();
/* We prefer Legacy I/O module over docking */
if (legacy_io_present()) {
legacy_io_init();
early_superio_config();
} else if (!dock_err && dock_present()) {
dock_connect();
early_superio_config();
}
/* Setup the console */
console_init();
/* Halt if there was a built in self test failure */
report_bist_failure(bist);
if (MCHBAR16(SSKPD) == 0xCAFE) {
printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n");
outb(0x6, 0xcf9);
halt();
}
/* Perform some early chipset initialization required
* before RAM initialization can work
*/
i945_early_initialization();
s3resume = southbridge_detect_s3_resume();
/* Enable SPD ROMs and DDR-II DRAM */
enable_smbus();
#if CONFIG_DEFAULT_CONSOLE_LOGLEVEL > 8
dump_spd_registers();
#endif
timestamp_add_now(TS_BEFORE_INITRAM);
sdram_initialize(s3resume ? 2 : 0, spd_addrmap);
timestamp_add_now(TS_AFTER_INITRAM);
/* Perform some initialization that must run before stage2 */
early_ich7_init();
/* This should probably go away. Until now it is required
* and mainboard specific
*/
rcba_config();
/* Chipset Errata! */
fixup_i945_errata();
/* Initialize the internal PCIe links before we go into stage2 */
i945_late_initialization(s3resume);
}

View File

@ -0,0 +1,24 @@
/*
* This file is part of the coreboot project.
*
* Copyright (c) 2011 Sven Schnelle <svens@stackframe.org>
*
* 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 MAINBOARD_LENOVO_X60_SMI_H
#define MAINBOARD_LENOVO_X60_SMI_H
#define SMI_DOCK_CONNECT 0x01
#define SMI_DOCK_DISCONNECT 0x02
#define SMI_BRIGHTNESS_UP 0x03
#define SMI_BRIGHTNESS_DOWN 0x04
#endif

View File

@ -0,0 +1,176 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008-2009 coresystems GmbH
*
* 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 <arch/io.h>
#include <console/console.h>
#include <cpu/x86/smm.h>
#include "southbridge/intel/i82801gx/nvs.h"
#include "southbridge/intel/i82801gx/i82801gx.h"
#include <ec/acpi/ec.h>
#include "dock.h"
#include "smi.h"
#define GPE_EC_SCI 12
#define LVTMA_BL_MOD_LEVEL 0x7af9 /* ATI Radeon backlight level */
static void mainboard_smm_init(void)
{
printk(BIOS_DEBUG, "initializing SMI\n");
/* Enable 0x1600/0x1600 register pair */
ec_set_bit(0x00, 0x05);
}
static void mainboard_smi_brightness_down(void)
{
u8 *bar;
if ((bar = (u8 *)pci_read_config32(PCI_DEV(1, 0, 0), 0x18))) {
printk(BIOS_DEBUG, "bar: %08X, level %02X\n", (unsigned int)bar,
*(bar+LVTMA_BL_MOD_LEVEL));
*(bar+LVTMA_BL_MOD_LEVEL) &= 0xf0;
if (*(bar+LVTMA_BL_MOD_LEVEL) > 0x10)
*(bar+LVTMA_BL_MOD_LEVEL) -= 0x10;
}
}
static void mainboard_smi_brightness_up(void)
{
u8 *bar;
if ((bar = (u8 *)pci_read_config32(PCI_DEV(1, 0, 0), 0x18))) {
printk(BIOS_DEBUG, "bar: %08X, level %02X\n", (unsigned int )bar,
*(bar+LVTMA_BL_MOD_LEVEL));
*(bar+LVTMA_BL_MOD_LEVEL) |= 0x0f;
if (*(bar+LVTMA_BL_MOD_LEVEL) < 0xf0)
*(bar+LVTMA_BL_MOD_LEVEL) += 0x10;
}
}
int mainboard_io_trap_handler(int smif)
{
static int smm_initialized;
if (!smm_initialized) {
mainboard_smm_init();
smm_initialized = 1;
}
switch (smif) {
case SMI_DOCK_CONNECT:
/* If there's an legacy I/O module present, we're not
* allowed to connect the Docking LPC Bus, as both Super I/O
* chips are using 0x2e as base address.
*/
if (legacy_io_present())
break;
if (!dock_connect()) {
/* set dock LED to indicate status */
ec_write(0x0c, 0x08);
ec_write(0x0c, 0x89);
} else {
/* blink dock LED to indicate failure */
ec_write(0x0c, 0xc8);
ec_write(0x0c, 0x09);
}
break;
case SMI_DOCK_DISCONNECT:
dock_disconnect();
ec_write(0x0c, 0x09);
ec_write(0x0c, 0x08);
break;
case SMI_BRIGHTNESS_UP:
mainboard_smi_brightness_up();
break;
case SMI_BRIGHTNESS_DOWN:
mainboard_smi_brightness_down();
break;
default:
return 0;
}
/* On success, the IO Trap Handler returns 1
* On failure, the IO Trap Handler returns a value != 1 */
return 1;
}
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);
switch(event) {
/* brightness up */
case 0x14:
mainboard_smi_brightness_up();
break;
/* brightness down */
case 0x15:
mainboard_smi_brightness_down();
break;
/* Fn-F9 Key */
case 0x18:
/* power loss */
case 0x27:
/* undock event */
case 0x50:
mainboard_io_trap_handler(SMI_DOCK_DISCONNECT);
break;
/* dock event */
case 0x37:
mainboard_io_trap_handler(SMI_DOCK_CONNECT);
break;
default:
break;
}
}
void mainboard_smi_gpi(u32 gpi)
{
if (gpi & (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 H8SCI to SCI */
gpi_route_interrupt(GPE_EC_SCI, GPI_IS_SCI);
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 H8SCI# to SMI */
gpi_route_interrupt(GPE_EC_SCI, GPI_IS_SMI);
break;
default:
break;
}
return 0;
}