blob: d476d5d6e64ae263323c41a1e0c5498107e13109 [file] [log] [blame]
Angel Ponsba38f372020-04-05 15:46:45 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Lee Leahyacb9c0b2015-07-02 11:55:18 -07002
Kyösti Mälkkibdaec072019-03-02 23:18:29 +02003#include <arch/io.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02004#include <device/mmio.h>
Dinesh Gehlotba09eb72023-01-17 05:06:10 +00005#include <gpio.h>
Lee Leahyacb9c0b2015-07-02 11:55:18 -07006#include <soc/iomap.h>
Dinesh Gehlotba09eb72023-01-17 05:06:10 +00007#include <soc/pm.h>
Lee Leahyacb9c0b2015-07-02 11:55:18 -07008
9#define SUSPEND_CYCLE 1
10#define RESUME_CYCLE 0
11#define LPC_FAMILY_NUMBER(gpio_pad) (gpio_pad / MAX_FAMILY_PAD_GPIO_NO)
12#define LPC_INTERNAL_PAD_NUM(gpio_pad) (gpio_pad % MAX_FAMILY_PAD_GPIO_NO)
13#define LPC_GPIO_OFFSET(gpio_pad) (FAMILY_PAD_REGS_OFF \
14 + (FAMILY_PAD_REGS_SIZE * LPC_FAMILY_NUMBER(gpio_pad) \
15 + (GPIO_REGS_SIZE * LPC_INTERNAL_PAD_NUM(gpio_pad))))
16
17#define LPC_AD2_MMIO_OFFSET LPC_GPIO_OFFSET(45)
18#define LPC_CLKRUN_MMIO_OFFSET LPC_GPIO_OFFSET(46)
19#define LPC_AD0_MMIO_OFFSET LPC_GPIO_OFFSET(47)
20#define LPC_FRAME_MMIO_OFFSET LPC_GPIO_OFFSET(48)
21#define LPC_AD3_MMIO_OFFSET LPC_GPIO_OFFSET(50)
22#define LPC_AD1_MMIO_OFFSET LPC_GPIO_OFFSET(52)
23
Lee Leahyacb9c0b2015-07-02 11:55:18 -070024/* Value written into pad control reg 0 in early init */
25#define PAD_CFG0_NATIVE(mode, term, inv_rx_tx) (PAD_GPIO_DISABLE \
26 | PAD_GPIOFG_HI_Z \
27 | PAD_MODE_SELECTION(mode) | PAD_PULL(term))
28
29#define PAD_CFG0_NATIVE_PU20K(mode) PAD_CFG0_NATIVE(mode, 9, 0) /* PU 20K */
30#define PAD_CFG0_NATIVE_PD20K(mode) PAD_CFG0_NATIVE(mode, 1, 0) /* PD 20K */
31#define PAD_CFG0_NATIVE_M1 PAD_CFG0_NATIVE(1, 0, 0) /* no pull */
32
33/*
34 * Configure value in LPC GPIO PADCFG0 registers. This function would be called
35 * to configure for low power/restore LPC GPIO lines
36 */
37static void lpc_gpio_config(u32 cycle)
38{
39 if (cycle == SUSPEND_CYCLE) { /* Suspend cycle */
Angel Ponsaee7ab22020-03-19 00:31:58 +010040 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_FRAME_MMIO_OFFSET),
Lee Leahyacb9c0b2015-07-02 11:55:18 -070041 PAD_CFG0_NATIVE_PU20K(1));
Angel Ponsaee7ab22020-03-19 00:31:58 +010042
43 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD0_MMIO_OFFSET),
Lee Leahyacb9c0b2015-07-02 11:55:18 -070044 PAD_CFG0_NATIVE_PU20K(1));
Angel Ponsaee7ab22020-03-19 00:31:58 +010045
46 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD1_MMIO_OFFSET),
Lee Leahyacb9c0b2015-07-02 11:55:18 -070047 PAD_CFG0_NATIVE_PU20K(1));
Angel Ponsaee7ab22020-03-19 00:31:58 +010048
49 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD2_MMIO_OFFSET),
Lee Leahyacb9c0b2015-07-02 11:55:18 -070050 PAD_CFG0_NATIVE_PU20K(1));
Angel Ponsaee7ab22020-03-19 00:31:58 +010051
52 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD3_MMIO_OFFSET),
Lee Leahyacb9c0b2015-07-02 11:55:18 -070053 PAD_CFG0_NATIVE_PU20K(1));
Angel Ponsaee7ab22020-03-19 00:31:58 +010054
55 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_CLKRUN_MMIO_OFFSET),
Lee Leahyacb9c0b2015-07-02 11:55:18 -070056 PAD_CFG0_NATIVE_PD20K(1));
Angel Ponsaee7ab22020-03-19 00:31:58 +010057
Lee Leahyacb9c0b2015-07-02 11:55:18 -070058 } else { /* Resume cycle */
Angel Ponsaee7ab22020-03-19 00:31:58 +010059 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_FRAME_MMIO_OFFSET),
Lee Leahyacb9c0b2015-07-02 11:55:18 -070060 PAD_CFG0_NATIVE_M1);
Angel Ponsaee7ab22020-03-19 00:31:58 +010061
62 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD0_MMIO_OFFSET),
Lee Leahyacb9c0b2015-07-02 11:55:18 -070063 PAD_CFG0_NATIVE_PU20K(1));
Angel Ponsaee7ab22020-03-19 00:31:58 +010064
65 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD1_MMIO_OFFSET),
Lee Leahyacb9c0b2015-07-02 11:55:18 -070066 PAD_CFG0_NATIVE_PU20K(1));
Angel Ponsaee7ab22020-03-19 00:31:58 +010067
68 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD2_MMIO_OFFSET),
Lee Leahyacb9c0b2015-07-02 11:55:18 -070069 PAD_CFG0_NATIVE_PU20K(1));
Angel Ponsaee7ab22020-03-19 00:31:58 +010070
71 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD3_MMIO_OFFSET),
Lee Leahyacb9c0b2015-07-02 11:55:18 -070072 PAD_CFG0_NATIVE_PU20K(1));
Angel Ponsaee7ab22020-03-19 00:31:58 +010073
74 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_CLKRUN_MMIO_OFFSET),
Lee Leahyacb9c0b2015-07-02 11:55:18 -070075 PAD_CFG0_NATIVE_M1);
76 }
77}
78
79/*
Angel Ponsaee7ab22020-03-19 00:31:58 +010080 * Configure LPC GPIO lines for low power
Lee Leahyacb9c0b2015-07-02 11:55:18 -070081 */
82void lpc_set_low_power(void)
83{
84 lpc_gpio_config(SUSPEND_CYCLE);
85}
86
87/*
88 * Configure GPIO lines early during romstage.
89 */
90void lpc_init(void)
91{
92 uint16_t pm1_sts;
93 uint32_t pm1_cnt;
94 int slp_type = 0;
95
96 /*
97 * On S3 resume re-initialize GPIO lines which were
98 * configured for low power during S3 entry.
99 */
100 pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS);
101 pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT);
102
103 if (pm1_sts & WAK_STS)
Aaron Durbin1b6196d2016-07-13 23:20:26 -0500104 slp_type = acpi_sleep_from_pm1(pm1_cnt);
Lee Leahyacb9c0b2015-07-02 11:55:18 -0700105
Aaron Durbin1b6196d2016-07-13 23:20:26 -0500106 if ((slp_type == ACPI_S3) || (slp_type == ACPI_S5))
Lee Leahyacb9c0b2015-07-02 11:55:18 -0700107 lpc_gpio_config(RESUME_CYCLE);
108}