1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <device/mmio.h>
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))))
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)
24 /* Value written into pad control reg 0 in early init */
25 #define PAD_CFG0_NATIVE(mode, term, inv_rx_tx) (PAD_GPIO_DISABLE \
27 | PAD_MODE_SELECTION(mode) | PAD_PULL(term))
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 */
34 * Configure value in LPC GPIO PADCFG0 registers. This function would be called
35 * to configure for low power/restore LPC GPIO lines
37 static void lpc_gpio_config(u32 cycle
)
39 if (cycle
== SUSPEND_CYCLE
) { /* Suspend cycle */
40 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE
+ LPC_FRAME_MMIO_OFFSET
),
41 PAD_CFG0_NATIVE_PU20K(1));
43 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE
+ LPC_AD0_MMIO_OFFSET
),
44 PAD_CFG0_NATIVE_PU20K(1));
46 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE
+ LPC_AD1_MMIO_OFFSET
),
47 PAD_CFG0_NATIVE_PU20K(1));
49 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE
+ LPC_AD2_MMIO_OFFSET
),
50 PAD_CFG0_NATIVE_PU20K(1));
52 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE
+ LPC_AD3_MMIO_OFFSET
),
53 PAD_CFG0_NATIVE_PU20K(1));
55 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE
+ LPC_CLKRUN_MMIO_OFFSET
),
56 PAD_CFG0_NATIVE_PD20K(1));
58 } else { /* Resume cycle */
59 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE
+ LPC_FRAME_MMIO_OFFSET
),
62 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE
+ LPC_AD0_MMIO_OFFSET
),
63 PAD_CFG0_NATIVE_PU20K(1));
65 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE
+ LPC_AD1_MMIO_OFFSET
),
66 PAD_CFG0_NATIVE_PU20K(1));
68 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE
+ LPC_AD2_MMIO_OFFSET
),
69 PAD_CFG0_NATIVE_PU20K(1));
71 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE
+ LPC_AD3_MMIO_OFFSET
),
72 PAD_CFG0_NATIVE_PU20K(1));
74 write32((void *)(COMMUNITY_GPSOUTHEAST_BASE
+ LPC_CLKRUN_MMIO_OFFSET
),
80 * Configure LPC GPIO lines for low power
82 void lpc_set_low_power(void)
84 lpc_gpio_config(SUSPEND_CYCLE
);
88 * Configure GPIO lines early during romstage.
97 * On S3 resume re-initialize GPIO lines which were
98 * configured for low power during S3 entry.
100 pm1_sts
= inw(ACPI_BASE_ADDRESS
+ PM1_STS
);
101 pm1_cnt
= inl(ACPI_BASE_ADDRESS
+ PM1_CNT
);
103 if (pm1_sts
& WAK_STS
)
104 slp_type
= acpi_sleep_from_pm1(pm1_cnt
);
106 if ((slp_type
== ACPI_S3
) || (slp_type
== ACPI_S5
))
107 lpc_gpio_config(RESUME_CYCLE
);