From patchwork Sun Apr 17 13:07:45 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: add ThinkPad T60 Date: Sun, 17 Apr 2011 13:07:45 -0000 From: Sven Schnelle X-Patchwork-Id: 2882 Message-Id: <871v1181r2.fsf@begreifnix.stackframe.org> To: coreboot@coreboot.org Hi List, the attached patch adds support for the ThinkPad T60 to coreboot. it is diffed against the existing X60 port. Signed-off-by: Sven Schnelle Acked-by: Stefan Reinauer Index: Kconfig =================================================================== --- Kconfig (revision 6509) +++ Kconfig (working copy) @@ -11,9 +11,14 @@ ThinkPad X60s (Model 1703) +config BOARD_LENOVO_T60 + bool "ThinkPad T60 / T60p" + help + endchoice source "src/mainboard/lenovo/x60/Kconfig" +source "src/mainboard/lenovo/t60/Kconfig" config MAINBOARD_VENDOR string Index: t60/Kconfig =================================================================== --- t60/Kconfig (revision 6509) +++ t60/Kconfig (working copy) @@ -1,4 +1,4 @@ -if BOARD_LENOVO_X60 +if BOARD_LENOVO_T60 config BOARD_SPECIFIC_OPTIONS # dummy def_bool y @@ -7,9 +7,9 @@ select CPU_INTEL_SOCKET_MFCPGA478 select NORTHBRIDGE_INTEL_I945GM select SOUTHBRIDGE_INTEL_I82801GX - select SOUTHBRIDGE_RICOH_RL5C476 select SUPERIO_NSC_PC87382 - select SUPERIO_NSC_PC87392 + select SUPERIO_NSC_PC87384 + select SOUTHBRIDGE_TI_PCI1X2X select EC_LENOVO_PMH7 select EC_LENOVO_H8 select BOARD_HAS_FADT @@ -26,7 +26,7 @@ config MAINBOARD_DIR string - default lenovo/x60 + default lenovo/t60 config DCACHE_RAM_BASE hex @@ -38,7 +38,7 @@ config MAINBOARD_PART_NUMBER string - default "ThinkPad X60 / X60s" + default "ThinkPad T60 / T60p" config MMCONF_BASE_ADDRESS hex @@ -56,4 +56,28 @@ int default 1 +config TI_PCMCIA_CARDBUS_CMDR + hex + default 0x0107 + +config TI_PCMCIA_CARDBUS_CLSR + hex + default 0x00 + +config TI_PCMCIA_CARDBUS_CLTR + hex + default 0x40 + +config TI_PCMCIA_CARDBUS_BCR + hex + default 0x07C0 + +config TI_PCMCIA_CARDBUS_SCR + hex + default 0x08449060 + +config TI_PCMCIA_CARDBUS_MRR + hex + default 0x00007522 + endif Index: t60/dock.c =================================================================== --- t60/dock.c (revision 6509) +++ t60/dock.c (working copy) @@ -26,8 +26,9 @@ #include #include #include "dock.h" +#include "superio/nsc/pc87384/pc87384.h" +#include "ec/acpi/ec.h" #include "southbridge/intel/i82801gx/i82801gx.h" -#include "superio/nsc/pc87392/pc87392.h" static void dlpc_write_register(int reg, int value) { @@ -59,6 +60,7 @@ dlpc_write_register(0xf1, mode); } + static void dock_gpio_set_mode(int port, int mode, int irq) { dock_write_register(0xf0, port); @@ -107,132 +109,99 @@ /* Activate DLPC */ dlpc_write_register(0x30, 0x01); - outb(0x07, 0x164c); - - timeout = 1000; - - while(!(inb(0x164c) & 8) && timeout--) - udelay(1000); - - if (!timeout) { - /* docking failed, disable DLPC switch */ - outb(0x00, 0x164c); - dlpc_write_register(0x30, 0x00); - return 1; - } - dlpc_gpio_init(); - return 0; } -int dock_connect(void) +static int dock_superio_init(void) { int timeout = 1000; - - /* Assert D_PLTRST# */ - outb(0xfe, 0x1680); - udelay(1000); - /* Deassert D_PLTRST# */ - outb(0xff, 0x1680); - /* startup 14.318MHz Clock */ - dock_write_register(0x29, 0x06); + dock_write_register(0x29, 0xa0); /* wait until clock is settled */ - while(!(dock_read_register(0x29) & 0x08) && timeout--) + while(!(dock_read_register(0x29) & 0x10) && timeout--) udelay(1000); if (!timeout) return 1; - /* Pin 6: CLKRUN - * Pin 72: #DR1 - * Pin 19: #SMI - * Pin 73: #MTR + /* set GPIO pins to Serial/Parallel Port + * functions */ - dock_write_register(0x24, 0x37); + dock_write_register(0x22, 0xeb); - /* PNF active HIGH */ - dock_write_register(0x25, 0xa0); + dock_write_register(0x07, PC87384_GPIO); + dock_write_register(0x60, 0x16); + dock_write_register(0x61, 0x20); - /* disable FDC */ - dock_write_register(0x26, 0x01); + dock_gpio_set_mode(0x00, PC87384_GPIO_PIN_DEBOUNCE | + PC87384_GPIO_PIN_PULLUP, 0x00); - /* Enable GPIO IRQ to #SMI */ - dock_write_register(0x28, 0x02); + dock_gpio_set_mode(0x01, PC87384_GPIO_PIN_TYPE_PUSH_PULL | + PC87384_GPIO_PIN_OE, 0x00); - /* select GPIO */ - dock_write_register(0x07, 0x07); + dock_gpio_set_mode(0x02, PC87384_GPIO_PIN_TYPE_PUSH_PULL | + PC87384_GPIO_PIN_OE, 0x00); - /* set base address */ - dock_write_register(0x60, 0x16); - dock_write_register(0x61, 0x20); + dock_gpio_set_mode(0x03, PC87384_GPIO_PIN_DEBOUNCE | + PC87384_GPIO_PIN_PULLUP, 0x00); - /* init GPIO pins */ - dock_gpio_set_mode(0x00, PC87392_GPIO_PIN_DEBOUNCE | - PC87392_GPIO_PIN_PULLUP, 0x00); + dock_gpio_set_mode(0x04, PC87384_GPIO_PIN_DEBOUNCE | + PC87384_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x01, PC87392_GPIO_PIN_DEBOUNCE | - PC87392_GPIO_PIN_PULLUP, - PC87392_GPIO_PIN_TRIGGERS_SMI); + dock_gpio_set_mode(0x05, PC87384_GPIO_PIN_DEBOUNCE | + PC87384_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x02, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x03, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x04, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x05, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x06, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x07, PC87392_GPIO_PIN_PULLUP, 0x02); + dock_gpio_set_mode(0x06, PC87384_GPIO_PIN_DEBOUNCE | + PC87384_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x10, PC87392_GPIO_PIN_DEBOUNCE | - PC87392_GPIO_PIN_PULLUP, - PC87392_GPIO_PIN_TRIGGERS_SMI); + dock_gpio_set_mode(0x07, PC87384_GPIO_PIN_DEBOUNCE | + PC87384_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x11, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x12, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x13, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x14, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x15, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x16, PC87392_GPIO_PIN_PULLUP | - PC87392_GPIO_PIN_OE , 0x00); + outb(0xfd, 0x1620); - dock_gpio_set_mode(0x17, PC87392_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); - dock_gpio_set_mode(0x20, PC87392_GPIO_PIN_TYPE_PUSH_PULL | - PC87392_GPIO_PIN_OE, 0x00); + /* clear GPIO events on PORT1*/ + outb(0xff, 0x1627); + outb(0x1F, 0x1628); + /* enable GPIO */ + dock_write_register(0x30, 0x01); + return 0; +} - dock_gpio_set_mode(0x21, PC87392_GPIO_PIN_TYPE_PUSH_PULL | - PC87392_GPIO_PIN_OE, 0x00); +int dock_connect(void) +{ + int timeout = 1000; - dock_gpio_set_mode(0x22, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x23, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x24, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x25, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x26, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x27, PC87392_GPIO_PIN_PULLUP, 0x00); + outb(0x07, 0x164c); - dock_gpio_set_mode(0x30, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x31, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x32, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x33, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x34, PC87392_GPIO_PIN_PULLUP, 0x00); + timeout = 1000; - dock_gpio_set_mode(0x35, PC87392_GPIO_PIN_PULLUP | - PC87392_GPIO_PIN_OE, 0x00); + while(!(inb(0x164c) & 8) && timeout--) + udelay(1000); - dock_gpio_set_mode(0x36, PC87392_GPIO_PIN_PULLUP, 0x00); - dock_gpio_set_mode(0x37, PC87392_GPIO_PIN_PULLUP, 0x00); + if (!timeout) { + /* docking failed, disable DLPC switch */ + outb(0x00, 0x164c); + dlpc_write_register(0x30, 0x00); + return 1; + } - /* enable GPIO */ - dock_write_register(0x30, 0x01); + /* Assert D_PLTRST# */ + outb(0xfe, 0x1680); + udelay(1000); + /* Deassert D_PLTRST# */ + outb(0xff, 0x1680); + udelay(10000); - outb(0x00, 0x1628); - outb(0x00, 0x1623); - outb(0x82, 0x1622); - outb(0xff, 0x1624); - - /* Enable USB and Ultrabay power */ - outb(0x03, 0x1628); - return 0; + return dock_superio_init(); } void dock_disconnect(void) @@ -245,5 +214,7 @@ int dock_present(void) { - return !((inb(DEFAULT_GPIOBASE + 0x0c) >> 13) & 1); + outb(0x61, 0x15ec); + return inb(0x15ee) & 1; } + Index: t60/romstage.c =================================================================== --- t60/romstage.c (revision 6509) +++ t60/romstage.c (working copy) @@ -43,40 +43,16 @@ { printk(BIOS_DEBUG, " GPIOS..."); - /* X60 GPIO: - 1: HDD_PRESENCE# - 6: Unknown (Pulled high by R215 to VCC3B) - 7: BDC_PRESENCE# - 8: H8_WAKE# - 9: RTC_BAT_IN# - 10: Unknown (Pulled high by R700 to VCC3M - 12: H8SCI# - 13: SLICE_ON_3M# - 14: Unknown (Pulled high by R321 to VCC3) - 15: Unknown (Pulled high by R258 to VCC3) - 19: Unknown (Pulled low by R594) - 21: Unknown (Pulled high by R145 to VCC3) - 22: FWH_WP# - 25: MDC_KILL# - 33: HDD_PRESENCE_2# - 35: CLKREQ_SATA# - 36: PLANARID0 - 37: PLANARID1 - 38: PLANARID2 - 39: PLANARID3 - 48: FWH_TBL# - */ - - outl(0x1f40f7c2, DEFAULT_GPIOBASE + 0x00); /* GPIO_USE_SEL */ - outl(0xe0e8ffc3, DEFAULT_GPIOBASE + 0x04); /* GP_IO_SEL */ - outl(0xfbf6ddfd, DEFAULT_GPIOBASE + 0x0c); /* GP_LVL */ + outl(0x1f48f7c2, DEFAULT_GPIOBASE + 0x00); /* GPIO_USE_SEL */ + outl(0xe0e0ffc3, DEFAULT_GPIOBASE + 0x04); /* GP_IO_SEL */ + outl(0xfbfefb7d, DEFAULT_GPIOBASE + 0x0c); /* GP_LVL */ /* Output Control Registers */ outl(0x00040000, DEFAULT_GPIOBASE + 0x18); /* GPO_BLINK */ /* Input Control Registers */ outl(0x000039ff, DEFAULT_GPIOBASE + 0x2c); /* GPI_INV */ - outl(0x000100f2, DEFAULT_GPIOBASE + 0x30); /* GPIO_USE_SEL2 */ - outl(0x000000f0, DEFAULT_GPIOBASE + 0x34); /* GP_IO_SEL2 */ - outl(0x00030043, DEFAULT_GPIOBASE + 0x38); /* GP_LVL */ + outl(0x000100f0, DEFAULT_GPIOBASE + 0x30); /* GPIO_USE_SEL2 */ + outl(0x000000f1, DEFAULT_GPIOBASE + 0x34); /* GP_IO_SEL2 */ + outl(0x000300a3, DEFAULT_GPIOBASE + 0x38); /* GP_LVL2 */ } static void ich7_enable_lpc(void) @@ -106,9 +82,9 @@ int timeout = 100000; device_t dev = PNP_DEV(0x2e, 3); - pnp_write_config(dev, 0x29, 0x06); + pnp_write_config(dev, 0x29, 0xa0); - while(!(pnp_read_config(dev, 0x29) & 0x08) && timeout--) + while(!(pnp_read_config(dev, 0x29) & 0x10) && timeout--) udelay(1000); /* Enable COM1 */ Index: t60/devicetree.cb =================================================================== --- t60/devicetree.cb (revision 6509) +++ t60/devicetree.cb (working copy) @@ -30,14 +30,21 @@ device pci_domain 0 on device pci 00.0 on # Host bridge - subsystemid 0x17aa 0x2017 + subsystemid 0x17aa 0x2015 end - device pci 02.0 on # VGA controller + device pci 01.0 on # PCI-e + device pci 00.0 on # VGA + subsystemid 0x17aa 0x20a4 + end + 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" @@ -63,8 +70,10 @@ device pci 1b.0 on # Audio Cnotroller subsystemid 0x17aa 0x2010 end - device pci 1c.0 on end # Ethernet - device pci 1c.1 on end # Atheros WLAN + device pci 1c.0 on # Ethernet + subsystemid 0x17aa 0x2001 + end + device pci 1c.1 on end # WLAN device pci 1d.0 on # USB UHCI subsystemid 0x17aa 0x200a end @@ -80,12 +89,21 @@ 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 0x2012 + end + 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 @@ -95,6 +113,7 @@ io 0x66 = 0x1604 end + register "config0" = "0xa6" register "config1" = "0x05" register "config2" = "0xa0" @@ -107,9 +126,11 @@ register "event3_enable" = "0xff" register "event4_enable" = "0xf4" register "event5_enable" = "0x3c" + register "event6_enable" = "0x80" register "wlan_enable" = "0x01" register "trackpoint_enable" = "0x03" + end chip superio/nsc/pc87382 device pnp 164e.2 on # IR @@ -129,7 +150,7 @@ end end - chip superio/nsc/pc87392 + chip superio/nsc/pc87384 device pnp 2e.0 off #FDC end @@ -166,7 +187,5 @@ subsystemid 0x17aa 0x200f end end - chip southbridge/ricoh/rl5c476 - end end end Index: t60/mptable.c =================================================================== --- t60/mptable.c (revision 6509) +++ t60/mptable.c (working copy) @@ -62,9 +62,7 @@ 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, 0x05, (0x00 << 2) | 0x00, 0x02, 0x10); /* Cardbus 5:00.0 */ - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x05, (0x00 << 2) | 0x01, 0x02, 0x11); /* Firewire 5:00.1 */ - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x05, (0x00 << 2) | 0x02, 0x02, 0x12); /* SDHC 5:00.2 */ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x06, (0x00 << 2) | 0x00, 0x02, 0x10); /* Cardbus 5:00.0 */ smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_HIGH, isa_bus, 0, MP_APIC_ALL, 0); smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_HIGH, isa_bus, 0, MP_APIC_ALL, 1); Index: t60/acpi/gpe.asl =================================================================== --- t60/acpi/gpe.asl (revision 6509) +++ t60/acpi/gpe.asl (working copy) @@ -6,16 +6,4 @@ /* Read EC register to clear wake status */ Store(\_SB.PCI0.LPCB.EC.WAKE, Local0) } - - /* SLICE_ON_3M GPE (Dock status) */ - Method(_L1D, 0, NotSerialized) - { - if (GP13) { - Or(GIV1, 0x20, GIV1) - Notify(\_SB.DOCK, 3) - } else { - And(GIV1, 0xdf, GIV1) - Notify(\_SB.DOCK, 0) - } - } } Index: t60/acpi/dock.asl =================================================================== --- t60/acpi/dock.asl (revision 6509) +++ t60/acpi/dock.asl (working copy) @@ -53,15 +53,39 @@ Method(_STA, 0, NotSerialized) { - Return (DSTA) + 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) + } + } }