xref: /aosp_15_r20/external/coreboot/src/soc/intel/braswell/lpc_init.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/io.h>
4 #include <device/mmio.h>
5 #include <gpio.h>
6 #include <soc/iomap.h>
7 #include <soc/pm.h>
8 
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 
24 /* 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  */
lpc_gpio_config(u32 cycle)37 static void lpc_gpio_config(u32 cycle)
38 {
39 	if (cycle == SUSPEND_CYCLE) { /* Suspend cycle */
40 		write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_FRAME_MMIO_OFFSET),
41 				PAD_CFG0_NATIVE_PU20K(1));
42 
43 		write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD0_MMIO_OFFSET),
44 				PAD_CFG0_NATIVE_PU20K(1));
45 
46 		write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD1_MMIO_OFFSET),
47 				PAD_CFG0_NATIVE_PU20K(1));
48 
49 		write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD2_MMIO_OFFSET),
50 				PAD_CFG0_NATIVE_PU20K(1));
51 
52 		write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD3_MMIO_OFFSET),
53 				PAD_CFG0_NATIVE_PU20K(1));
54 
55 		write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_CLKRUN_MMIO_OFFSET),
56 				PAD_CFG0_NATIVE_PD20K(1));
57 
58 	} else { /* Resume cycle */
59 		write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_FRAME_MMIO_OFFSET),
60 				PAD_CFG0_NATIVE_M1);
61 
62 		write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD0_MMIO_OFFSET),
63 				PAD_CFG0_NATIVE_PU20K(1));
64 
65 		write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD1_MMIO_OFFSET),
66 				PAD_CFG0_NATIVE_PU20K(1));
67 
68 		write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD2_MMIO_OFFSET),
69 				PAD_CFG0_NATIVE_PU20K(1));
70 
71 		write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_AD3_MMIO_OFFSET),
72 				PAD_CFG0_NATIVE_PU20K(1));
73 
74 		write32((void *)(COMMUNITY_GPSOUTHEAST_BASE + LPC_CLKRUN_MMIO_OFFSET),
75 				PAD_CFG0_NATIVE_M1);
76 	}
77 }
78 
79 /*
80  * Configure LPC GPIO lines for low power
81  */
lpc_set_low_power(void)82 void lpc_set_low_power(void)
83 {
84 	lpc_gpio_config(SUSPEND_CYCLE);
85 }
86 
87 /*
88  * Configure GPIO lines early during romstage.
89  */
lpc_init(void)90 void 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)
104 		slp_type = acpi_sleep_from_pm1(pm1_cnt);
105 
106 	if ((slp_type == ACPI_S3) || (slp_type == ACPI_S5))
107 		lpc_gpio_config(RESUME_CYCLE);
108 }
109