Stefan Reinauer (stefan.reinauer@coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/822
-gerrit
commit f62e2d8ad35b6f7e1b6c56c04361fece45f9650b Author: Stefan Reinauer reinauer@chromium.org Date: Fri Mar 30 15:04:07 2012 -0700
Add support for ITE IT8772F SuperI/O chip
Change-Id: I8e80c22eb0f3cb68f2457be6b2e7894df60ed632 Signed-off-by: Duncan Laurie dlaurie@google.com Signed-off-by: Stefan Reinauer reinauer@google.com --- src/superio/ite/Kconfig | 2 + src/superio/ite/Makefile.inc | 1 + src/superio/ite/it8772f/Makefile.inc | 21 ++ src/superio/ite/it8772f/acpi/superio.asl | 299 ++++++++++++++++++++++++++++++ src/superio/ite/it8772f/chip.h | 57 ++++++ src/superio/ite/it8772f/early_serial.c | 131 +++++++++++++ src/superio/ite/it8772f/it8772f.h | 120 ++++++++++++ src/superio/ite/it8772f/superio.c | 250 +++++++++++++++++++++++++ 8 files changed, 881 insertions(+), 0 deletions(-)
diff --git a/src/superio/ite/Kconfig b/src/superio/ite/Kconfig index d045bf4..5d92a96 100644 --- a/src/superio/ite/Kconfig +++ b/src/superio/ite/Kconfig @@ -38,3 +38,5 @@ config SUPERIO_ITE_IT8718F bool config SUPERIO_ITE_IT8721F bool +config SUPERIO_ITE_IT8772F + bool diff --git a/src/superio/ite/Makefile.inc b/src/superio/ite/Makefile.inc index 1e734fe..fa44ff8 100644 --- a/src/superio/ite/Makefile.inc +++ b/src/superio/ite/Makefile.inc @@ -25,3 +25,4 @@ subdirs-y += it8712f subdirs-y += it8716f subdirs-y += it8718f subdirs-y += it8721f +subdirs-y += it8772f diff --git a/src/superio/ite/it8772f/Makefile.inc b/src/superio/ite/it8772f/Makefile.inc new file mode 100644 index 0000000..d001c61 --- /dev/null +++ b/src/superio/ite/it8772f/Makefile.inc @@ -0,0 +1,21 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. +## +## 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; either version 2 of the License, or +## (at your option) any later version. +## +## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +ramstage-$(CONFIG_SUPERIO_ITE_IT8772F) += superio.c diff --git a/src/superio/ite/it8772f/acpi/superio.asl b/src/superio/ite/it8772f/acpi/superio.asl new file mode 100644 index 0000000..5bb45fa --- /dev/null +++ b/src/superio/ite/it8772f/acpi/superio.asl @@ -0,0 +1,299 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +// Scope is _SB.PCI0.LPCB + +Device (SIO) { + Name (_ADR, 0x2E) + OperationRegion (SIOA, SystemIO, 0x2E, 0x02) + Field (SIOA, ByteAcc, NoLock, Preserve) + { + SI2E, 8, + SI2F, 8, + } + + IndexField (SI2E, SI2F, ByteAcc, NoLock, Preserve) + { + Offset (0x02), + SCNT, 8, /* Configure Control */ + Offset (0x07), + SLDN, 8, /* Logical Device Number */ + Offset (0x30), + SACT, 8, /* Activate */ + Offset (0x60), + IO0H, 8, /* Base Address 0 MSB */ + IO0L, 8, /* Base Address 0 LSB */ + Offset (0x62), + IO1H, 8, /* Base Address 1 MSB */ + IO1L, 8, /* Base Address 1 LSB */ + Offset (0x70), + IQ00, 8, /* Interrupt Select */ + } + + Name (SFDC, 0) /* Floppy Disk Controller */ + Name (SSP1, 1) /* Serial Port 1 */ + Name (SENV, 4) /* Environment Controller */ + Name (SKBC, 5) /* Keyboard */ + Name (SKBM, 6) /* Mouse */ + Name (SGPI, 7) /* GPIO */ + Name (SINF, 10) /* Consumer IR */ + + Method (ENTR, 0, NotSerialized) + { + Store (0x87, SI2E) + Store (0x01, SI2E) + Store (0x55, SI2E) + Store (0x55, SI2E) + } + + Method (EXIT, 0, NotSerialized) + { + Store (0x02, SCNT) + } + + /* Parse activate register for an LDN */ + Method (ISEN, 1, NotSerialized) + { + ENTR () + Store (Arg0, SLDN) + Store (SACT, Local0) + EXIT () + + /* Check if it exists */ + If (LEqual (Local0, 0xFF)) + { + Return (0x00) + } + + /* Check if activated */ + If (LEqual (Local0, One)) + { + Return (0x0F) + } + Else + { + Return (0x0D) + } + } + + /* Enable an LDN via the activate register */ + Method (SENA, 1, NotSerialized) + { + ENTR () + Store (Arg0, SLDN) + Store (One, SACT) + EXIT () + } + + /* Disable an LDN via the activate register */ + Method (SDIS, 1, NotSerialized) + { + ENTR () + Store (Arg0, SLDN) + Store (Zero, SACT) + EXIT () + } + +#ifdef SIO_ENABLE_ENVC + Device (ENVC) { + Name (_HID, EISAID ("PNP0C02")) + Name (_UID, 10) + + Method (_STA, 0, NotSerialized) { + Return (ISEN (SENV)) + } + + Name (_CRS, ResourceTemplate () + { + IO (Decode16, SIO_ENVC_IO0, SIO_ENVC_IO0, 0x08, 0x08) + IO (Decode16, SIO_ENVC_IO1, SIO_ENVC_IO1, 0x04, 0x04) + }) + + Name (_PRS, ResourceTemplate () + { + IO (Decode16, SIO_ENVC_IO0, SIO_ENVC_IO0, 0x08, 0x08) + IO (Decode16, SIO_ENVC_IO1, SIO_ENVC_IO1, 0x04, 0x04) + }) + + OperationRegion (ECAP, SystemIO, SIO_ENVC_IO0, 0x07) + Field (ECAP, ByteAcc, NoLock, Preserve) + { + Offset (0x05), + ECAI, 8, // Address Index Register + ECAD, 8, // Address Data Register + } + + // Registers for thermal zone implementations + IndexField (ECAI, ECAD, ByteAcc, NoLock, Preserve) + { + Offset (0x29), + TIN1, 8, // TMPIN1 Reading + TIN2, 8, // TMPIN2 Reading + TIN3, 8, // TMPIN3 Reading + Offset (0x6b), + F2PS, 8, // FAN2 PWM Setting + Offset (0x73), + F3PS, 8, // FAN3 PWM Setting + } + } +#endif + +#ifdef SIO_ENABLE_GPIO + Device (GPIO) { + Name (_HID, EISAID ("PNP0C02")) + Name (_UID, 11) + + Method (_STA, 0, NotSerialized) { + Return (0x0F) + } + + Name (_CRS, ResourceTemplate () + { + IO (Decode16, SIO_GPIO_IO0, SIO_GPIO_IO0, 0x01, 0x01) + IO (Decode16, SIO_GPIO_IO1, SIO_GPIO_IO1, 0x08, 0x08) + }) + + Name (_PRS, ResourceTemplate () + { + IO (Decode16, SIO_GPIO_IO0, SIO_GPIO_IO0, 0x01, 0x01) + IO (Decode16, SIO_GPIO_IO1, SIO_GPIO_IO1, 0x08, 0x08) + }) + } +#endif + +#ifdef SIO_ENABLE_COM1 + Device (COM1) { + Name (_HID, EISAID ("PNP0501")) + Name (_UID, 1) + + Method (_STA, 0, NotSerialized) { + Return (ISEN (SSP1)) + } + + Name (_CRS, ResourceTemplate () + { + IO (Decode16, 0x03F8, 0x03F8, 0x08, 0x08) + IRQNoFlags () {4} + }) + + Name (_PRS, ResourceTemplate () + { + IO (Decode16, 0x03F8, 0x03F8, 0x08, 0x08) + IRQNoFlags () {4} + }) + } +#endif + +#ifdef SIO_ENABLE_PS2K + Device (PS2K) // Keyboard + { + Name (_HID, EISAID("PNP0303")) + Name (_CID, EISAID("PNP030B")) + + Method (_STA, 0, NotSerialized) { + Return (ISEN (SKBC)) + } + + Name (_CRS, ResourceTemplate() + { + IO (Decode16, 0x60, 0x60, 0x01, 0x01) + IO (Decode16, 0x64, 0x64, 0x01, 0x01) + IRQNoFlags () {1} + }) + + Name (_PRS, ResourceTemplate() + { + IO (Decode16, 0x60, 0x60, 0x01, 0x01) + IO (Decode16, 0x64, 0x64, 0x01, 0x01) + IRQNoFlags () {1} + }) + } +#endif + +#ifdef SIO_ENABLE_PS2M + Device (PS2M) // Mouse + { + Name (_HID, EISAID("PNP0F13")) + + Method (_STA, 0, NotSerialized) { + Return (ISEN (SKBM)) + } + + Name (_CRS, ResourceTemplate() + { + IRQNoFlags () {12} + }) + + Name (_PRS, ResourceTemplate() + { + IRQNoFlags () {12} + }) + } +#endif + +#ifdef SIO_ENABLE_FDC0 + Device (FDC0) // Floppy controller + { + Name (_HID, EISAID ("PNP0700")) + + Method (_STA, 0, NotSerialized) { + Return (ISEN (SFDC)) + } + + Name (_CRS, ResourceTemplate() + { + IO (Decode16, 0x03F0, 0x03F0, 0x01, 0x06) + IO (Decode16, 0x03F7, 0x03F7, 0x01, 0x01) + IRQNoFlags () {6} + DMA (Compatibility, NotBusMaster, Transfer8) {2} + }) + + Name (_PRS, ResourceTemplate() + { + IO (Decode16, 0x03F0, 0x03F0, 0x01, 0x06) + IO (Decode16, 0x03F7, 0x03F7, 0x01, 0x01) + IRQNoFlags () {6} + DMA (Compatibility, NotBusMaster, Transfer8) {2} + }) + } +#endif + +#ifdef SIO_ENABLE_INFR + Device (INFR) // Infrared controller + { + Name (_HID, EISAID ("PNP0510")) + + Method (_STA, 0, NotSerialized) { + Return (ISEN (SINF)) + } + + Name (_CRS, ResourceTemplate() + { + IO (Decode16, SIO_INFR_IO0, SIO_INFR_IO0, 0x08, 0x08) + IRQNoFlags () { SIO_INFR_IRQ } + }) + + Name (_PRS, ResourceTemplate() + { + IO (Decode16, SIO_INFR_IO0, SIO_INFR_IO0, 0x08, 0x08) + IRQNoFlags () { SIO_INFR_IRQ } + }) + } +#endif +} diff --git a/src/superio/ite/it8772f/chip.h b/src/superio/ite/it8772f/chip.h new file mode 100644 index 0000000..e91f6fa --- /dev/null +++ b/src/superio/ite/it8772f/chip.h @@ -0,0 +1,57 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SUPERIO_ITE_IT8772F_CHIP_H +#define SUPERIO_ITE_IT8772F_CHIP_H + +#include <device/device.h> +#include <pc80/keyboard.h> +#include <uart8250.h> + +extern struct chip_operations superio_ite_it8772f_ops; + +struct superio_ite_it8772f_config { + struct pc_keyboard keyboard; + + /* GPIO SimpleIO register values via devicetree.cb */ + u8 gpio_set1; + u8 gpio_set2; + u8 gpio_set3; + u8 gpio_set4; + u8 gpio_set5; + u8 gpio_set6; + + u8 skip_keyboard; + + /* + * Enable external temperature sensor to use PECI GetTemp() + * command and store in register TMPIN 1, 2, or 3. + */ + u8 peci_tmpin; + + /* + * Enable a FAN for sofware control. + */ + u8 fan1_enable; + u8 fan2_enable; + u8 fan3_enable; +}; + +#endif diff --git a/src/superio/ite/it8772f/early_serial.c b/src/superio/ite/it8772f/early_serial.c new file mode 100644 index 0000000..0721060 --- /dev/null +++ b/src/superio/ite/it8772f/early_serial.c @@ -0,0 +1,131 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <arch/romcc_io.h> +#include <device/pnp_def.h> +#include "it8772f.h" + +/* The base address is 0x2e or 0x4e, depending on config bytes. */ +#define SIO_BASE IT8772F_BASE +#define SIO_INDEX SIO_BASE +#define SIO_DATA (SIO_BASE + 1) + +/* Global configuration registers. */ +#define IT8772F_CONFIG_REG_CC 0x02 /* Configure Control (write-only). */ +#define IT8772F_CONFIG_REG_LDN 0x07 /* Logical Device Number. */ +#define IT8772F_CONFIG_REG_CLOCKSEL 0x23 /* Clock Selection. */ +#define IT8772F_CONFIG_REG_MFC 0x2a /* Multi-function control */ +#define IT8772F_CONFIG_REG_WATCHDOG 0x72 /* Watchdog control. */ + +u8 it8772f_sio_read(u8 index) +{ + outb(index, SIO_BASE); + return inb(SIO_DATA); +} + +void it8772f_sio_write(u8 index, u8 value) +{ + outb(index, SIO_BASE); + outb(value, SIO_DATA); +} + +static void it8772f_enter_conf(void) +{ + u16 port = SIO_BASE; + + outb(0x87, port); + outb(0x01, port); + outb(0x55, port); + outb((port == 0x4e) ? 0xaa : 0x55, port); +} + +static void it8772f_exit_conf(void) +{ + it8772f_sio_write(IT8772F_CONFIG_REG_CC, 0x02); +} + +/* Select 24MHz CLKIN (48MHz is the default). */ +void it8772f_24mhz_clkin(void) +{ + it8772f_enter_conf(); + it8772f_sio_write(IT8772F_CONFIG_REG_LDN, 0x00); + it8772f_sio_write(IT8772F_CONFIG_REG_CLOCKSEL, 0x1); + it8772f_exit_conf(); +} + +/* + * LDN 7, reg 0x2a - needed for S3, or memory power will be cut off. + * + * Enable 3VSBSW#. (For System Suspend-to-RAM) + * 0: 3VSBSW# will be always inactive. + * 1: 3VSBSW# enabled. It will be (NOT SUSB#) NAND SUSC#. + */ +void it8772f_enable_3vsbsw(void) +{ + it8772f_enter_conf(); + it8772f_sio_write(IT8772F_CONFIG_REG_LDN, IT8772F_GPIO); + it8772f_sio_write(IT8772F_CONFIG_REG_MFC, 0x80); + it8772f_exit_conf(); +} + +void it8772f_kill_watchdog(void) +{ + it8772f_enter_conf(); + it8772f_sio_write(IT8772F_CONFIG_REG_LDN, IT8772F_GPIO); + it8772f_sio_write(IT8772F_CONFIG_REG_WATCHDOG, 0x00); + it8772f_exit_conf(); +} + +/* Enable the serial port(s). */ +void it8772f_enable_serial(device_t dev, u16 iobase) +{ + it8772f_enter_conf(); + it8772f_sio_write(IT8772F_CONFIG_REG_LDN, dev & 0xff); + it8772f_sio_write(PNP_IDX_IO0, (iobase >> 8) & 0xff); + it8772f_sio_write(PNP_IDX_IO0+1, iobase & 0xff); + it8772f_sio_write(PNP_IDX_EN, 1); + it8772f_exit_conf(); +} + +/* Set AC resume to be up to the Southbridge */ +void it8772f_ac_resume_southbridge(void) +{ + it8772f_enter_conf(); + it8772f_sio_write(IT8772F_CONFIG_REG_LDN, IT8772F_EC); + it8772f_sio_write(0xf4, 0x60); + it8772f_exit_conf(); +} + +/* Configure a set of GPIOs */ +void it8772f_gpio_setup(int set, u8 select, u8 polarity, u8 pullup, + u8 output, u8 enable) +{ + set--; /* Set 1 is offset 0 */ + it8772f_enter_conf(); + it8772f_sio_write(IT8772F_CONFIG_REG_LDN, IT8772F_GPIO); + if (set < 5) { + it8772f_sio_write(GPIO_REG_SELECT(set), select); + it8772f_sio_write(GPIO_REG_ENABLE(set), enable); + it8772f_sio_write(GPIO_REG_POLARITY(set), polarity); + } + it8772f_sio_write(GPIO_REG_OUTPUT(set), output); + it8772f_sio_write(GPIO_REG_PULLUP(set), pullup); + it8772f_exit_conf(); +} diff --git a/src/superio/ite/it8772f/it8772f.h b/src/superio/ite/it8772f/it8772f.h new file mode 100644 index 0000000..1ec82e1 --- /dev/null +++ b/src/superio/ite/it8772f/it8772f.h @@ -0,0 +1,120 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SUPERIO_ITE_IT8772F_IT8772F_H +#define SUPERIO_ITE_IT8772F_IT8772F_H + +#define IT8772F_BASE 0x2e + +#define IT8772F_FDC 0x00 /* Floppy disk controller */ +#define IT8772F_SP1 0x01 /* Com1 */ +#define IT8772F_EC 0x04 /* Environment controller */ +#define IT8772F_KBCK 0x05 /* Keyboard */ +#define IT8772F_KBCM 0x06 /* Mouse */ +#define IT8772F_GPIO 0x07 /* GPIO */ +#define IT8772F_IR 0x0a /* Consumer IR */ + +/* Environmental Controller interface */ +#define IT8772F_INTERFACE_SELECT 0x0a +#define IT8772F_INTERFACE_PSEUDO_EOC (1 << 7) +#define IT8772F_INTERFACE_SMB_ENABLE (1 << 6) +#define IT8772F_INTERFACE_SEL_DISABLE (0 << 4) +#define IT8772F_INTERFACE_SEL_SST_SLAVE (1 << 4) +#define IT8772F_INTERFACE_SEL_PECI (2 << 4) +#define IT8772F_INTERFACE_SEL_SST_HOST (3 << 4) +#define IT8772F_INTERFACE_CLOCK_32MHZ (0 << 3) +#define IT8772F_INTERFACE_CLOCK_24MHZ (1 << 3) +#define IT8772F_INTERFACE_SPEED_TOLERANCE (1 << 2) +#define IT8772F_INTERFACE_PECI_AWFCS (1 << 0) +#define IT8772F_FAN_TAC2_READ 0x0e +#define IT8772F_FAN_TAC3_READ 0x0f +#define IT8772F_FAN_MAIN_CTL 0x13 +#define IT8772F_FAN_MAIN_CTL_TAC_SMART(x) (1 << ((x)-1)) +#define IT8772F_FAN_MAIN_CTL_TAC_EN(x) (1 << ((x)+3)) +#define IT8772F_FAN_CTL_MODE 0x14 +#define IT8772F_FAN_CTL_ON(x) (1 << ((x)-1)) +#define IT8772F_FAN_PWM_MIN_DUTY (1 << 3) +#define IT8772F_FAN_PWM_CLOCK_48MHZ (0 << 4) +#define IT8772F_FAN_PWM_CLOCK_24MHZ (1 << 4) +#define IT8772F_FAN_PWM_CLOCK_8MHZ (3 << 4) +#define IT8772F_FAN_PWM_CLOCK_6MHZ (4 << 4) +#define IT8772F_FAN_PWM_CLOCK_3MHZ (5 << 4) +#define IT8772F_FAN_PWM_CLOCK_1_5MHZ (6 << 4) +#define IT8772F_FAN_PWM_CLOCK_51KHZ (7 << 4) +#define IT8772F_FAN_CTL_POLARITY_LOW (0 << 7) +#define IT8772F_FAN_CTL_POLARITY_HIGH (1 << 7) +#define IT8772F_FAN_CTL2_PWM_MODE 0x16 +#define IT8772F_FAN_CTL3_PWM_MODE 0x17 +#define IT8772F_FAN_CTL_PWM_MODE_SOFTWARE (0 << 7) +#define IT8772F_FAN_CTL_PWM_MODE_AUTOMATIC (1 << 7) +#define IT8772F_ADC_TEMP_CHANNEL_ENABLE 0x51 +#define IT8772F_FAN_CTL2_PWM_START 0x6b +#define IT8772F_FAN_CTL2_AUTO_MODE 0x6c +#define IT8772F_FAN_CTL3_PWM_START 0x73 +#define IT8772F_FAN_CTL3_AUTO_MODE 0x74 +#define IT8772F_FAN_CTL_AUTO_SMOOTHING_DIS (0 << 7) +#define IT8772F_FAN_CTL_AUTO_SMOOTHING_EN (1 << 7) +#define IT8772F_EXTEMP_STATUS 0x88 +#define IT8772F_EXTEMP_ADDRESS 0x89 +#define IT8772F_EXTEMP_WRITE_LENGTH 0x8a +#define IT8772F_EXTEMP_READ_LENGTH 0x8b +#define IT8772F_EXTEMP_COMMAND 0x8c +#define IT8772F_EXTEMP_WRITE_DATA_2 0x8d +#define IT8772F_EXTEMP_CONTROL 0x8e +#define IT8772F_EXTEMP_CONTROL_AUTO_32HZ (0 << 6) +#define IT8772F_EXTEMP_CONTROL_AUTO_16HZ (1 << 6) +#define IT8772F_EXTEMP_CONTROL_AUTO_8HZ (2 << 6) +#define IT8772F_EXTEMP_CONTROL_AUTO_4HZ (3 << 6) +#define IT8772F_EXTEMP_CONTROL_AUTO_START (1 << 5) +#define IT8772F_EXTEMP_CONTROL_AUTO_ABORT (1 << 4) +#define IT8772F_EXTEMP_CONTROL_AUTO_TWO_DOMAIN (1 << 3) +#define IT8772F_EXTEMP_CONTROL_CONTENTION (1 << 2) +#define IT8772F_EXTEMP_CONTROL_SST_IDLE_HIGH (1 << 1) +#define IT8772F_EXTEMP_CONTROL_START (1 << 0) + +/* Standard PECI GetTemp */ +#define PECI_CLIENT_ADDRESS 0x30 +#define PECI_GETTEMP_COMMAND 0x01 +#define PECI_GETTEMP_WRITE_LENGTH 0x01 +#define PECI_GETTEMP_READ_LENGTH 0x02 + +/* GPIO interface */ +#define IT8772F_GPIO_LED_BLINK1_PINMAP 0xf8 +#define IT8772F_GPIO_LED_BLINK1_CONTROL 0xf9 + +#define GPIO_REG_SELECT(x) (0x25 + (x)) +#define GPIO_REG_POLARITY(x) (0xb0 + (x)) +#define GPIO_REG_PULLUP(x) (0xb8 + (x)) +#define GPIO_REG_ENABLE(x) (0xc0 + (x)) +#define GPIO_REG_OUTPUT(x) (0xc8 + (x)) + +#ifndef __ROMCC__ +u8 it8772f_sio_read(u8 index); +void it8772f_sio_write(u8 index, u8 value); +void it8772f_enable_serial(device_t dev, u16 iobase); +void it8772f_kill_watchdog(void); +void it8772f_24mhz_clkin(void); +void it8772f_enable_3vsbsw(void); +void it8772f_ac_resume_southbridge(void); +void it8772f_gpio_setup(int set, u8 func_select, u8 polarity, u8 pullup, + u8 output, u8 enable); +#endif + +#endif diff --git a/src/superio/ite/it8772f/superio.c b/src/superio/ite/it8772f/superio.c new file mode 100644 index 0000000..1361ef2 --- /dev/null +++ b/src/superio/ite/it8772f/superio.c @@ -0,0 +1,250 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <device/device.h> +#include <device/pnp.h> +#include <uart8250.h> +#include <pc80/keyboard.h> +#include <arch/io.h> +#include <stdlib.h> +#include "chip.h" +#include "it8772f.h" + +static void pnp_enter_ext_func_mode(device_t dev) +{ + u16 port = dev->path.pnp.port; + + outb(0x87, port); + outb(0x01, port); + outb(0x55, port); + outb((port == 0x4e) ? 0xaa : 0x55, port); +} + +static void pnp_exit_ext_func_mode(device_t dev) +{ + pnp_write_config(dev, 0x02, 0x02); +} + +static inline u8 it8772f_envc_read(struct resource *res, u8 addr) +{ + outb(addr, res->base + 5); + return inb(res->base + 6); +} + +static inline void it8772f_envc_write(struct resource *res, u8 addr, u8 value) +{ + outb(addr, res->base + 5); + outb(value, res->base + 6); +} + +/* + * Setup External Temperature to read via PECI into TMPINx register + */ +static void it8772f_enable_peci(struct resource *res, int tmpin) +{ + if (tmpin < 1 || tmpin > 3) + return; + + /* Enable PECI interface */ + it8772f_envc_write(res, IT8772F_INTERFACE_SELECT, + IT8772F_INTERFACE_SEL_PECI | + IT8772F_INTERFACE_SPEED_TOLERANCE); + + /* Setup External Temperature using PECI GetTemp */ + it8772f_envc_write(res, IT8772F_EXTEMP_ADDRESS, + PECI_CLIENT_ADDRESS); + it8772f_envc_write(res, IT8772F_EXTEMP_COMMAND, + PECI_GETTEMP_COMMAND); + it8772f_envc_write(res, IT8772F_EXTEMP_WRITE_LENGTH, + PECI_GETTEMP_WRITE_LENGTH); + it8772f_envc_write(res, IT8772F_EXTEMP_READ_LENGTH, + PECI_GETTEMP_READ_LENGTH); + it8772f_envc_write(res, IT8772F_EXTEMP_CONTROL, + IT8772F_EXTEMP_CONTROL_AUTO_4HZ | + IT8772F_EXTEMP_CONTROL_AUTO_START); + + /* External Temperature reported in TMPINx register */ + it8772f_envc_write(res, IT8772F_ADC_TEMP_CHANNEL_ENABLE, + (tmpin & 3) << 6); +} + +/* + * Setup a FAN PWM interface for software control + */ +static void it8772f_enable_fan(struct resource *res, int fan) +{ + u8 reg; + + if (fan < 1 || fan > 3) + return; + + /* Enable 6MHz (23.43kHz PWM) active high output */ + reg = it8772f_envc_read(res, IT8772F_FAN_CTL_MODE); + reg |= IT8772F_FAN_CTL_ON(fan) | + IT8772F_FAN_PWM_CLOCK_6MHZ | + IT8772F_FAN_CTL_POLARITY_HIGH; + it8772f_envc_write(res, IT8772F_FAN_CTL_MODE, reg); + + /* Enable output in smart mode */ + reg = it8772f_envc_read(res, IT8772F_FAN_MAIN_CTL); + reg |= IT8772F_FAN_MAIN_CTL_TAC_SMART(fan); + reg |= IT8772F_FAN_MAIN_CTL_TAC_EN(fan); + it8772f_envc_write(res, IT8772F_FAN_MAIN_CTL, reg); + + switch (fan) { + case 2: + /* Enable software operation */ + it8772f_envc_write(res, IT8772F_FAN_CTL2_PWM_MODE, + IT8772F_FAN_CTL_PWM_MODE_SOFTWARE); + /* Disable Smoothing */ + it8772f_envc_write(res, IT8772F_FAN_CTL2_AUTO_MODE, + IT8772F_FAN_CTL_AUTO_SMOOTHING_DIS); + /* Set a default medium fan speed */ + it8772f_envc_write(res, IT8772F_FAN_CTL2_PWM_START, 0x80); + break; + case 3: + /* Enable software operation */ + it8772f_envc_write(res, IT8772F_FAN_CTL3_PWM_MODE, + IT8772F_FAN_CTL_PWM_MODE_SOFTWARE); + /* Disable Smoothing */ + it8772f_envc_write(res, IT8772F_FAN_CTL3_AUTO_MODE, + IT8772F_FAN_CTL_AUTO_SMOOTHING_DIS); + /* Set a default medium fan speed */ + it8772f_envc_write(res, IT8772F_FAN_CTL3_PWM_START, 0x80); + break; + } +} + +static void it8772f_init(device_t dev) +{ + struct superio_ite_it8772f_config *conf = dev->chip_info; + struct resource *res; + + if (!dev->enabled) + return; + + switch (dev->path.pnp.device) { + case IT8772F_EC: + res = find_resource(dev, PNP_IDX_IO0); + if (!res) + break; + + /* Enable PECI if configured */ + it8772f_enable_peci(res, conf->peci_tmpin); + + /* Enable FANx if configured */ + if (conf->fan1_enable) + it8772f_enable_fan(res, 1); + if (conf->fan2_enable) + it8772f_enable_fan(res, 2); + if (conf->fan3_enable) + it8772f_enable_fan(res, 3); + break; + case IT8772F_GPIO: + /* Set GPIO output levels */ + res = find_resource(dev, PNP_IDX_IO1); + if (res) { + if (conf->gpio_set1) + outb(conf->gpio_set1, res->base + 0); + if (conf->gpio_set2) + outb(conf->gpio_set2, res->base + 1); + if (conf->gpio_set3) + outb(conf->gpio_set3, res->base + 2); + if (conf->gpio_set4) + outb(conf->gpio_set4, res->base + 3); + if (conf->gpio_set5) + outb(conf->gpio_set5, res->base + 4); + if (conf->gpio_set6) + outb(conf->gpio_set6, res->base + 5); + } + break; + case IT8772F_KBCK: + if (!conf->skip_keyboard) { + set_kbc_ps2_mode(); + pc_keyboard_init(&conf->keyboard); + } + break; + case IT8772F_KBCM: + break; + case IT8772F_IR: + break; + } +} + +static void it8772f_pnp_set_resources(device_t dev) +{ + pnp_enter_ext_func_mode(dev); + pnp_set_resources(dev); + pnp_exit_ext_func_mode(dev); +} + +static void it8772f_pnp_enable_resources(device_t dev) +{ + pnp_enter_ext_func_mode(dev); + pnp_enable_resources(dev); + pnp_exit_ext_func_mode(dev); +} + +static void it8772f_pnp_enable(device_t dev) +{ + pnp_enter_ext_func_mode(dev); + pnp_set_logical_device(dev); + pnp_set_enable(dev, !!dev->enabled); + pnp_exit_ext_func_mode(dev); +} + +static struct device_operations ops = { + .read_resources = pnp_read_resources, + .set_resources = it8772f_pnp_set_resources, + .enable_resources = it8772f_pnp_enable_resources, + .enable = it8772f_pnp_enable, + .init = it8772f_init, +}; + +static struct pnp_info pnp_dev_info[] = { + /* Floppy Disk Controller */ + { &ops, IT8772F_FDC, PNP_IO0 | PNP_IRQ0, {0x0ff8, 0}, }, + /* Serial Port 1 */ + { &ops, IT8772F_SP1, PNP_IO0 | PNP_IRQ0, {0x0ff8, 0}, }, + /* Environmental Controller */ + { &ops, IT8772F_EC, PNP_IO0 | PNP_IO1 | PNP_IRQ0, + {0x0ff8, 0}, {0x0ffc, 4}, }, + /* KBC Keyboard */ + { &ops, IT8772F_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, + {0x0fff, 0}, {0x0fff, 4}, }, + /* KBC Mouse */ + { &ops, IT8772F_KBCM, PNP_IRQ0, }, + /* 27 GPIOs */ + { &ops, IT8772F_GPIO, PNP_IO0 | PNP_IO1, + {0x0fff, 0}, {0x0ff8, 0}, }, + /* Infrared */ + { &ops, IT8772F_IR, PNP_IO0 | PNP_IRQ0, {0x0ff8, 0}, }, +}; + +static void enable_dev(struct device *dev) +{ + pnp_enable_devices(dev, &pnp_ops, + ARRAY_SIZE(pnp_dev_info), pnp_dev_info); +} + +struct chip_operations superio_ite_it8772f_ops = { + CHIP_NAME("ITE IT8772F Super I/O") + .enable_dev = enable_dev, +};