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