122 lines
3.8 KiB
C
122 lines
3.8 KiB
C
|
/*
|
||
|
* This file is part of the coreboot project.
|
||
|
*
|
||
|
* Copyright (C) 2015 Intel Corp.
|
||
|
*
|
||
|
* 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 <soc/gpio.h>
|
||
|
#include <soc/pm.h>
|
||
|
#include <soc/iomap.h>
|
||
|
|
||
|
#define SUSPEND_CYCLE 1
|
||
|
#define RESUME_CYCLE 0
|
||
|
#define LPC_FAMILY_NUMBER(gpio_pad) (gpio_pad / MAX_FAMILY_PAD_GPIO_NO)
|
||
|
#define LPC_INTERNAL_PAD_NUM(gpio_pad) (gpio_pad % MAX_FAMILY_PAD_GPIO_NO)
|
||
|
#define LPC_GPIO_OFFSET(gpio_pad) (FAMILY_PAD_REGS_OFF \
|
||
|
+ (FAMILY_PAD_REGS_SIZE * LPC_FAMILY_NUMBER(gpio_pad) \
|
||
|
+ (GPIO_REGS_SIZE * LPC_INTERNAL_PAD_NUM(gpio_pad))))
|
||
|
|
||
|
#define LPC_AD2_MMIO_OFFSET LPC_GPIO_OFFSET(45)
|
||
|
#define LPC_CLKRUN_MMIO_OFFSET LPC_GPIO_OFFSET(46)
|
||
|
#define LPC_AD0_MMIO_OFFSET LPC_GPIO_OFFSET(47)
|
||
|
#define LPC_FRAME_MMIO_OFFSET LPC_GPIO_OFFSET(48)
|
||
|
#define LPC_AD3_MMIO_OFFSET LPC_GPIO_OFFSET(50)
|
||
|
#define LPC_AD1_MMIO_OFFSET LPC_GPIO_OFFSET(52)
|
||
|
|
||
|
|
||
|
/* Value written into pad control reg 0 in early init */
|
||
|
#define PAD_CFG0_NATIVE(mode, term, inv_rx_tx) (PAD_GPIO_DISABLE \
|
||
|
| PAD_GPIOFG_HI_Z \
|
||
|
| PAD_MODE_SELECTION(mode) | PAD_PULL(term))
|
||
|
|
||
|
#define PAD_CFG0_NATIVE_PU20K(mode) PAD_CFG0_NATIVE(mode, 9, 0) /* PU 20K */
|
||
|
#define PAD_CFG0_NATIVE_PD20K(mode) PAD_CFG0_NATIVE(mode, 1, 0) /* PD 20K */
|
||
|
#define PAD_CFG0_NATIVE_M1 PAD_CFG0_NATIVE(1, 0, 0) /* no pull */
|
||
|
|
||
|
/*
|
||
|
* Configure value in LPC GPIO PADCFG0 registers. This function would be called
|
||
|
* to configure for low power/restore LPC GPIO lines
|
||
|
*/
|
||
|
static void lpc_gpio_config(u32 cycle)
|
||
|
{
|
||
|
if (cycle == SUSPEND_CYCLE) { /* Suspend cycle */
|
||
|
write32((void *)(COMMUNITY_GPSOUTHEAST_BASE +
|
||
|
LPC_FRAME_MMIO_OFFSET),
|
||
|
PAD_CFG0_NATIVE_PU20K(1));
|
||
|
write32((void *)(COMMUNITY_GPSOUTHEAST_BASE +
|
||
|
LPC_AD0_MMIO_OFFSET),
|
||
|
PAD_CFG0_NATIVE_PU20K(1));
|
||
|
write32((void *)(COMMUNITY_GPSOUTHEAST_BASE +
|
||
|
LPC_AD1_MMIO_OFFSET),
|
||
|
PAD_CFG0_NATIVE_PU20K(1));
|
||
|
write32((void *)(COMMUNITY_GPSOUTHEAST_BASE +
|
||
|
LPC_AD2_MMIO_OFFSET),
|
||
|
PAD_CFG0_NATIVE_PU20K(1));
|
||
|
write32((void *)(COMMUNITY_GPSOUTHEAST_BASE +
|
||
|
LPC_AD3_MMIO_OFFSET),
|
||
|
PAD_CFG0_NATIVE_PU20K(1));
|
||
|
write32((void *)(COMMUNITY_GPSOUTHEAST_BASE +
|
||
|
LPC_CLKRUN_MMIO_OFFSET),
|
||
|
PAD_CFG0_NATIVE_PD20K(1));
|
||
|
} else { /* Resume cycle */
|
||
|
write32((void *)(COMMUNITY_GPSOUTHEAST_BASE +
|
||
|
LPC_FRAME_MMIO_OFFSET),
|
||
|
PAD_CFG0_NATIVE_M1);
|
||
|
write32((void *)(COMMUNITY_GPSOUTHEAST_BASE +
|
||
|
LPC_AD0_MMIO_OFFSET),
|
||
|
PAD_CFG0_NATIVE_PU20K(1));
|
||
|
write32((void *)(COMMUNITY_GPSOUTHEAST_BASE +
|
||
|
LPC_AD1_MMIO_OFFSET),
|
||
|
PAD_CFG0_NATIVE_PU20K(1));
|
||
|
write32((void *)(COMMUNITY_GPSOUTHEAST_BASE +
|
||
|
LPC_AD2_MMIO_OFFSET),
|
||
|
PAD_CFG0_NATIVE_PU20K(1));
|
||
|
write32((void *)(COMMUNITY_GPSOUTHEAST_BASE +
|
||
|
LPC_AD3_MMIO_OFFSET),
|
||
|
PAD_CFG0_NATIVE_PU20K(1));
|
||
|
write32((void *)(COMMUNITY_GPSOUTHEAST_BASE +
|
||
|
LPC_CLKRUN_MMIO_OFFSET),
|
||
|
PAD_CFG0_NATIVE_M1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* configure LPC GPIO lines for low power
|
||
|
*/
|
||
|
void lpc_set_low_power(void)
|
||
|
{
|
||
|
lpc_gpio_config(SUSPEND_CYCLE);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Configure GPIO lines early during romstage.
|
||
|
*/
|
||
|
void lpc_init(void)
|
||
|
{
|
||
|
uint16_t pm1_sts;
|
||
|
uint32_t pm1_cnt;
|
||
|
int slp_type = 0;
|
||
|
|
||
|
/*
|
||
|
* On S3 resume re-initialize GPIO lines which were
|
||
|
* configured for low power during S3 entry.
|
||
|
*/
|
||
|
pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS);
|
||
|
pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
|
||
|
|
||
|
if (pm1_sts & WAK_STS)
|
||
|
slp_type = (pm1_cnt & SLP_TYP) >> SLP_TYP_SHIFT;
|
||
|
|
||
|
if ((slp_type == SLP_TYP_S3) || (slp_type == SLP_TYP_S5))
|
||
|
lpc_gpio_config(RESUME_CYCLE);
|
||
|
}
|