driver-y += pmh7.c
+smm-$(CONFIG_HAVE_SMI_HANDLER) += pmh7.c
+romstage-y += pmh7.c
outb(val, EC_LENOVO_PMH7_DATA);
}
+#ifndef __PRE_RAM__
+#ifndef __SMM__
static void enable_dev(device_t dev)
{
struct ec_lenovo_pmh7_config *conf = dev->chip_info;
CHIP_NAME("Lenovo Power Management Hardware Hub 7")
.enable_dev = enable_dev,
};
+#endif
+#endif
#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);
/* Select DLPC module */
dlpc_write_register(0x07, 0x19);
- /* DLPC Base Address 0x164c */
- dlpc_write_register(0x60, 0x16);
- dlpc_write_register(0x61, 0x4c);
+ /* 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;
}
/* set GPIO pins to Serial/Parallel Port
* functions
*/
- dock_write_register(0x22, 0xeb);
+ dock_write_register(0x22, 0xa9);
dock_write_register(0x07, PC87384_GPIO);
dock_write_register(0x60, 0x16);
{
int timeout = 1000;
- outb(0x07, 0x164c);
+ outb(0x07, DLPC_CONTROL);
timeout = 1000;
- while(!(inb(0x164c) & 8) && timeout--)
+ while(!(inb(DLPC_CONTROL) & 8) && timeout--)
udelay(1000);
if (!timeout) {
/* docking failed, disable DLPC switch */
- outb(0x00, 0x164c);
+ outb(0x00, DLPC_CONTROL);
dlpc_write_register(0x30, 0x00);
return 1;
}
void dock_disconnect(void)
{
/* disconnect LPC bus */
- outb(0x00, 0x164c);
+ outb(0x00, DLPC_CONTROL);
/* Assert PLTRST and DLPCPD */
outb(0xfc, 0x1680);
}
int dock_present(void)
{
- outb(0x61, 0x15ec);
- return inb(0x15ee) & 1;
+ 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();
+}
extern void dock_disconnect(void);
extern int dock_present(void);
extern int dlpc_init(void);
+
+extern int legacy_io_present(void);
+extern void legacy_io_init(void);
#endif
static void mainboard_enable(device_t dev)
{
+ struct southbridge_intel_i82801gx_config *config;
device_t dev0, idedev;
u8 defaults_loaded = 0;
ec_write(0x0c, 0xc7);
idedev = dev_find_slot(0, PCI_DEVFN(0x1f,1));
- if (idedev && idedev->chip_info && h8_ultrabay_device_present()) {
- struct southbridge_intel_i82801gx_config *config = idedev->chip_info;
+
+ 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);
switch (smif) {
case SMI_DOCK_CONNECT:
- dlpc_init();
+ /* 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);
void main(unsigned long bist)
{
u32 reg32;
- int boot_mode = 0;
+ int boot_mode = 0, dock_err;
const u8 spd_addrmap[2 * DIMM_SOCKETS] = { 0x50, 0x52, 0x51, 0x53 };
if (bist == 0)
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_ich7_gpios();
- /* dock_init initializes the DLPC switch on
- * thinpad side, so this is required even
- * if we're undocked.
- */
- if (!dlpc_init() && dock_present()) {
+ 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();
- /* Set up the console */
}
#if CONFIG_USBDEBUG
early_usbdebug_init();
#endif
+ /* Setup the console */
console_init();
/* Halt if there was a built in self test failure */