1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * This file contains platform specific structure definitions
4 * and init function used by Cannon Lake Point PCH.
5 *
6 * Copyright (c) 2022, Intel Corporation.
7 * All Rights Reserved.
8 *
9 */
10
11 #include <linux/smp.h>
12 #include <linux/suspend.h>
13 #include <asm/msr.h>
14 #include "core.h"
15
16 /* Cannon Lake: PGD PFET Enable Ack Status Register(s) bitmap */
17 const struct pmc_bit_map cnp_pfear_map[] = {
18 {"PMC", BIT(0)},
19 {"OPI-DMI", BIT(1)},
20 {"SPI/eSPI", BIT(2)},
21 {"XHCI", BIT(3)},
22 {"SPA", BIT(4)},
23 {"SPB", BIT(5)},
24 {"SPC", BIT(6)},
25 {"GBE", BIT(7)},
26
27 {"SATA", BIT(0)},
28 {"HDA_PGD0", BIT(1)},
29 {"HDA_PGD1", BIT(2)},
30 {"HDA_PGD2", BIT(3)},
31 {"HDA_PGD3", BIT(4)},
32 {"SPD", BIT(5)},
33 {"LPSS", BIT(6)},
34 {"LPC", BIT(7)},
35
36 {"SMB", BIT(0)},
37 {"ISH", BIT(1)},
38 {"P2SB", BIT(2)},
39 {"NPK_VNN", BIT(3)},
40 {"SDX", BIT(4)},
41 {"SPE", BIT(5)},
42 {"Fuse", BIT(6)},
43 {"SBR8", BIT(7)},
44
45 {"CSME_FSC", BIT(0)},
46 {"USB3_OTG", BIT(1)},
47 {"EXI", BIT(2)},
48 {"CSE", BIT(3)},
49 {"CSME_KVM", BIT(4)},
50 {"CSME_PMT", BIT(5)},
51 {"CSME_CLINK", BIT(6)},
52 {"CSME_PTIO", BIT(7)},
53
54 {"CSME_USBR", BIT(0)},
55 {"CSME_SUSRAM", BIT(1)},
56 {"CSME_SMT1", BIT(2)},
57 {"CSME_SMT4", BIT(3)},
58 {"CSME_SMS2", BIT(4)},
59 {"CSME_SMS1", BIT(5)},
60 {"CSME_RTC", BIT(6)},
61 {"CSME_PSF", BIT(7)},
62
63 {"SBR0", BIT(0)},
64 {"SBR1", BIT(1)},
65 {"SBR2", BIT(2)},
66 {"SBR3", BIT(3)},
67 {"SBR4", BIT(4)},
68 {"SBR5", BIT(5)},
69 {"CSME_PECI", BIT(6)},
70 {"PSF1", BIT(7)},
71
72 {"PSF2", BIT(0)},
73 {"PSF3", BIT(1)},
74 {"PSF4", BIT(2)},
75 {"CNVI", BIT(3)},
76 {"UFS0", BIT(4)},
77 {"EMMC", BIT(5)},
78 {"SPF", BIT(6)},
79 {"SBR6", BIT(7)},
80
81 {"SBR7", BIT(0)},
82 {"NPK_AON", BIT(1)},
83 {"HDA_PGD4", BIT(2)},
84 {"HDA_PGD5", BIT(3)},
85 {"HDA_PGD6", BIT(4)},
86 {"PSF6", BIT(5)},
87 {"PSF7", BIT(6)},
88 {"PSF8", BIT(7)},
89 {}
90 };
91
92 static const struct pmc_bit_map *ext_cnp_pfear_map[] = {
93 /*
94 * Check intel_pmc_core_ids[] users of cnp_reg_map for
95 * a list of core SoCs using this.
96 */
97 cnp_pfear_map,
98 NULL
99 };
100
101 static const struct pmc_bit_map cnp_slps0_dbg0_map[] = {
102 {"AUDIO_D3", BIT(0)},
103 {"OTG_D3", BIT(1)},
104 {"XHCI_D3", BIT(2)},
105 {"LPIO_D3", BIT(3)},
106 {"SDX_D3", BIT(4)},
107 {"SATA_D3", BIT(5)},
108 {"UFS0_D3", BIT(6)},
109 {"UFS1_D3", BIT(7)},
110 {"EMMC_D3", BIT(8)},
111 {}
112 };
113
114 static const struct pmc_bit_map cnp_slps0_dbg1_map[] = {
115 {"SDIO_PLL_OFF", BIT(0)},
116 {"USB2_PLL_OFF", BIT(1)},
117 {"AUDIO_PLL_OFF", BIT(2)},
118 {"OC_PLL_OFF", BIT(3)},
119 {"MAIN_PLL_OFF", BIT(4)},
120 {"XOSC_OFF", BIT(5)},
121 {"LPC_CLKS_GATED", BIT(6)},
122 {"PCIE_CLKREQS_IDLE", BIT(7)},
123 {"AUDIO_ROSC_OFF", BIT(8)},
124 {"HPET_XOSC_CLK_REQ", BIT(9)},
125 {"PMC_ROSC_SLOW_CLK", BIT(10)},
126 {"AON2_ROSC_GATED", BIT(11)},
127 {"CLKACKS_DEASSERTED", BIT(12)},
128 {}
129 };
130
131 static const struct pmc_bit_map cnp_slps0_dbg2_map[] = {
132 {"MPHY_CORE_GATED", BIT(0)},
133 {"CSME_GATED", BIT(1)},
134 {"USB2_SUS_GATED", BIT(2)},
135 {"DYN_FLEX_IO_IDLE", BIT(3)},
136 {"GBE_NO_LINK", BIT(4)},
137 {"THERM_SEN_DISABLED", BIT(5)},
138 {"PCIE_LOW_POWER", BIT(6)},
139 {"ISH_VNNAON_REQ_ACT", BIT(7)},
140 {"ISH_VNN_REQ_ACT", BIT(8)},
141 {"CNV_VNNAON_REQ_ACT", BIT(9)},
142 {"CNV_VNN_REQ_ACT", BIT(10)},
143 {"NPK_VNNON_REQ_ACT", BIT(11)},
144 {"PMSYNC_STATE_IDLE", BIT(12)},
145 {"ALST_GT_THRES", BIT(13)},
146 {"PMC_ARC_PG_READY", BIT(14)},
147 {}
148 };
149
150 const struct pmc_bit_map *cnp_slps0_dbg_maps[] = {
151 cnp_slps0_dbg0_map,
152 cnp_slps0_dbg1_map,
153 cnp_slps0_dbg2_map,
154 NULL
155 };
156
157 const struct pmc_bit_map cnp_ltr_show_map[] = {
158 {"SOUTHPORT_A", CNP_PMC_LTR_SPA},
159 {"SOUTHPORT_B", CNP_PMC_LTR_SPB},
160 {"SATA", CNP_PMC_LTR_SATA},
161 {"GIGABIT_ETHERNET", CNP_PMC_LTR_GBE},
162 {"XHCI", CNP_PMC_LTR_XHCI},
163 {"Reserved", CNP_PMC_LTR_RESERVED},
164 {"ME", CNP_PMC_LTR_ME},
165 /* EVA is Enterprise Value Add, doesn't really exist on PCH */
166 {"EVA", CNP_PMC_LTR_EVA},
167 {"SOUTHPORT_C", CNP_PMC_LTR_SPC},
168 {"HD_AUDIO", CNP_PMC_LTR_AZ},
169 {"CNV", CNP_PMC_LTR_CNV},
170 {"LPSS", CNP_PMC_LTR_LPSS},
171 {"SOUTHPORT_D", CNP_PMC_LTR_SPD},
172 {"SOUTHPORT_E", CNP_PMC_LTR_SPE},
173 {"CAMERA", CNP_PMC_LTR_CAM},
174 {"ESPI", CNP_PMC_LTR_ESPI},
175 {"SCC", CNP_PMC_LTR_SCC},
176 {"ISH", CNP_PMC_LTR_ISH},
177 {"UFSX2", CNP_PMC_LTR_UFSX2},
178 {"EMMC", CNP_PMC_LTR_EMMC},
179 /*
180 * Check intel_pmc_core_ids[] users of cnp_reg_map for
181 * a list of core SoCs using this.
182 */
183 {"WIGIG", ICL_PMC_LTR_WIGIG},
184 {"THC0", TGL_PMC_LTR_THC0},
185 {"THC1", TGL_PMC_LTR_THC1},
186 /* Below two cannot be used for LTR_IGNORE */
187 {"CURRENT_PLATFORM", CNP_PMC_LTR_CUR_PLT},
188 {"AGGREGATED_SYSTEM", CNP_PMC_LTR_CUR_ASLT},
189 {}
190 };
191
192 const struct pmc_reg_map cnp_reg_map = {
193 .pfear_sts = ext_cnp_pfear_map,
194 .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
195 .slp_s0_res_counter_step = SPT_PMC_SLP_S0_RES_COUNTER_STEP,
196 .slps0_dbg_maps = cnp_slps0_dbg_maps,
197 .ltr_show_sts = cnp_ltr_show_map,
198 .msr_sts = msr_map,
199 .slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET,
200 .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
201 .regmap_length = CNP_PMC_MMIO_REG_LEN,
202 .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
203 .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES,
204 .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
205 .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
206 .ltr_ignore_max = CNP_NUM_IP_IGN_ALLOWED,
207 .etr3_offset = ETR3_OFFSET,
208 };
209
210
211 /*
212 * Disable C1 auto-demotion
213 *
214 * Aggressive C1 auto-demotion may lead to failure to enter the deepest C-state
215 * during suspend-to-idle, causing high power consumption. To prevent this, we
216 * disable C1 auto-demotion during suspend and re-enable on resume.
217 *
218 * Note that, although MSR_PKG_CST_CONFIG_CONTROL has 'package' in its name, it
219 * is actually a per-core MSR on client platforms, affecting only a single CPU.
220 * Therefore, it must be configured on all online CPUs. The online cpu mask is
221 * unchanged during the phase of suspend/resume as user space is frozen.
222 */
223
224 static DEFINE_PER_CPU(u64, pkg_cst_config);
225
disable_c1_auto_demote(void * unused)226 static void disable_c1_auto_demote(void *unused)
227 {
228 int cpunum = smp_processor_id();
229 u64 val;
230
231 rdmsrq(MSR_PKG_CST_CONFIG_CONTROL, val);
232 per_cpu(pkg_cst_config, cpunum) = val;
233 val &= ~NHM_C1_AUTO_DEMOTE;
234 wrmsrq(MSR_PKG_CST_CONFIG_CONTROL, val);
235
236 pr_debug("%s: cpu:%d cst %llx\n", __func__, cpunum, val);
237 }
238
restore_c1_auto_demote(void * unused)239 static void restore_c1_auto_demote(void *unused)
240 {
241 int cpunum = smp_processor_id();
242
243 wrmsrq(MSR_PKG_CST_CONFIG_CONTROL, per_cpu(pkg_cst_config, cpunum));
244
245 pr_debug("%s: cpu:%d cst %llx\n", __func__, cpunum,
246 per_cpu(pkg_cst_config, cpunum));
247 }
248
s2idle_cpu_quirk(smp_call_func_t func)249 static void s2idle_cpu_quirk(smp_call_func_t func)
250 {
251 if (pm_suspend_via_firmware())
252 return;
253
254 on_each_cpu(func, NULL, true);
255 }
256
cnl_suspend(struct pmc_dev * pmcdev)257 void cnl_suspend(struct pmc_dev *pmcdev)
258 {
259 s2idle_cpu_quirk(disable_c1_auto_demote);
260
261 /*
262 * Due to a hardware limitation, the GBE LTR blocks PC10
263 * when a cable is attached. To unblock PC10 during suspend,
264 * tell the PMC to ignore it.
265 */
266 pmc_core_send_ltr_ignore(pmcdev, 3, 1);
267 }
268
cnl_resume(struct pmc_dev * pmcdev)269 int cnl_resume(struct pmc_dev *pmcdev)
270 {
271 s2idle_cpu_quirk(restore_c1_auto_demote);
272
273 pmc_core_send_ltr_ignore(pmcdev, 3, 0);
274
275 return pmc_core_resume_common(pmcdev);
276 }
277
278 struct pmc_dev_info cnp_pmc_dev = {
279 .map = &cnp_reg_map,
280 .suspend = cnl_suspend,
281 .resume = cnl_resume,
282 };
283
284