static int pch_power_options(const void *blob, int node, pci_dev_t dev) { u8 reg8; u16 reg16, pmbase; u32 reg32; const char *state; int pwr_on; int nmi_option; int ret; /* * Which state do we want to goto after g3 (power restored)? * 0 == S0 Full On * 1 == S5 Soft Off * * If the option is not existent (Laptops), use Kconfig setting. * TODO([email protected]): Make this configurable */ pwr_on = MAINBOARD_POWER_ON; reg16 = pci_read_config16(dev, GEN_PMCON_3); reg16 &= 0xfffe; switch (pwr_on) { case MAINBOARD_POWER_OFF: reg16 |= 1; state = "off"; break; case MAINBOARD_POWER_ON: reg16 &= ~1; state = "on"; break; case MAINBOARD_POWER_KEEP: reg16 &= ~1; state = "state keep"; break; default: state = "undefined"; } reg16 &= ~(3 << 4); /* SLP_S4# Assertion Stretch 4s */ reg16 |= (1 << 3); /* SLP_S4# Assertion Stretch Enable */ reg16 &= ~(1 << 10); reg16 |= (1 << 11); /* SLP_S3# Min Assertion Width 50ms */ reg16 |= (1 << 12); /* Disable SLP stretch after SUS well */ pci_write_config16(dev, GEN_PMCON_3, reg16); debug("Set power %s after power failure.\n", state); /* Set up NMI on errors. */ reg8 = inb(0x61); reg8 &= 0x0f; /* Higher Nibble must be 0 */ reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */ reg8 |= (1 << 2); /* PCI SERR# Disable for now */ outb(reg8, 0x61); reg8 = inb(0x70); /* TODO([email protected]): Make this configurable */ nmi_option = NMI_OFF; if (nmi_option) { debug("NMI sources enabled.\n"); reg8 &= ~(1 << 7); /* Set NMI. */ } else { debug("NMI sources disabled.\n"); /* Can't mask NMI from PCI-E and NMI_NOW */ reg8 |= (1 << 7); } outb(reg8, 0x70); /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */ reg16 = pci_read_config16(dev, GEN_PMCON_1); reg16 &= ~(3 << 0); /* SMI# rate 1 minute */ reg16 &= ~(1 << 10); /* Disable BIOS_PCI_EXP_EN for native PME */ #if DEBUG_PERIODIC_SMIS /* Set DEBUG_PERIODIC_SMIS in pch.h to debug using periodic SMIs */ reg16 |= (3 << 0); /* Periodic SMI every 8s */ #endif pci_write_config16(dev, GEN_PMCON_1, reg16); /* Set the board's GPI routing. */ ret = pch_gpi_routing(blob, node, dev); if (ret) return ret; pmbase = pci_read_config16(dev, 0x40) & 0xfffe; writel(pmbase + GPE0_EN, fdtdec_get_int(blob, node, "intel,gpe0-enable", 0)); writew(pmbase + ALT_GP_SMI_EN, fdtdec_get_int(blob, node, "intel,alt-gp-smi-enable", 0)); /* Set up power management block and determine sleep mode */ reg32 = inl(pmbase + 0x04); /* PM1_CNT */ reg32 &= ~(7 << 10); /* SLP_TYP */ reg32 |= (1 << 0); /* SCI_EN */ outl(reg32, pmbase + 0x04); /* Clear magic status bits to prevent unexpected wake */ setbits_le32(RCB_REG(0x3310), (1 << 4) | (1 << 5) | (1 << 0)); clrbits_le32(RCB_REG(0x3f02), 0xf); return 0; }
static void pch_power_options(device_t dev) { u8 reg8; u16 reg16, pmbase; u32 reg32; const char *state; /* Get the chip configuration */ config_t *config = dev->chip_info; int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL; int nmi_option; /* Which state do we want to goto after g3 (power restored)? * 0 == S0 Full On * 1 == S5 Soft Off * * If the option is not existent (Laptops), use Kconfig setting. */ get_option(&pwr_on, "power_on_after_fail"); reg16 = pci_read_config16(dev, GEN_PMCON_3); reg16 &= 0xfffe; switch (pwr_on) { case MAINBOARD_POWER_OFF: reg16 |= 1; state = "off"; break; case MAINBOARD_POWER_ON: reg16 &= ~1; state = "on"; break; case MAINBOARD_POWER_KEEP: reg16 &= ~1; state = "state keep"; break; default: state = "undefined"; } reg16 &= ~(3 << 4); /* SLP_S4# Assertion Stretch 4s */ reg16 |= (1 << 3); /* SLP_S4# Assertion Stretch Enable */ reg16 &= ~(1 << 10); reg16 |= (1 << 11); /* SLP_S3# Min Assertion Width 50ms */ reg16 |= (1 << 12); /* Disable SLP stretch after SUS well */ pci_write_config16(dev, GEN_PMCON_3, reg16); printk(BIOS_INFO, "Set power %s after power failure.\n", state); /* Set up NMI on errors. */ reg8 = inb(0x61); reg8 &= 0x0f; /* Higher Nibble must be 0 */ reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */ // reg8 &= ~(1 << 2); /* PCI SERR# Enable */ reg8 |= (1 << 2); /* PCI SERR# Disable for now */ outb(reg8, 0x61); reg8 = inb(0x70); nmi_option = NMI_OFF; get_option(&nmi_option, "nmi"); if (nmi_option) { printk(BIOS_INFO, "NMI sources enabled.\n"); reg8 &= ~(1 << 7); /* Set NMI. */ } else { printk(BIOS_INFO, "NMI sources disabled.\n"); reg8 |= ( 1 << 7); /* Can't mask NMI from PCI-E and NMI_NOW */ } outb(reg8, 0x70); /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */ reg16 = pci_read_config16(dev, GEN_PMCON_1); reg16 &= ~(3 << 0); // SMI# rate 1 minute reg16 &= ~(1 << 10); // Disable BIOS_PCI_EXP_EN for native PME #if DEBUG_PERIODIC_SMIS /* Set DEBUG_PERIODIC_SMIS in pch.h to debug using * periodic SMIs. */ reg16 |= (3 << 0); // Periodic SMI every 8s #endif pci_write_config16(dev, GEN_PMCON_1, reg16); // Set the board's GPI routing. pch_gpi_routing(dev); pmbase = pci_read_config16(dev, 0x40) & 0xfffe; outl(config->gpe0_en, pmbase + GPE0_EN); outw(config->alt_gp_smi_en, pmbase + ALT_GP_SMI_EN); /* Set up power management block and determine sleep mode */ reg32 = inl(pmbase + 0x04); // PM1_CNT reg32 &= ~(7 << 10); // SLP_TYP reg32 |= (1 << 0); // SCI_EN outl(reg32, pmbase + 0x04); /* Clear magic status bits to prevent unexpected wake */ reg32 = RCBA32(0x3310); reg32 |= (1 << 4)|(1 << 5)|(1 << 0); RCBA32(0x3310) = reg32; }