1 // SPDX-License-Identifier: GPL-2.0
3 * This file contains platform specific structure definitions
4 * and init function used by Cannon Lake Point PCH.
6 * Copyright (c) 2022, Intel Corporation.
11 #include <linux/smp.h>
12 #include <linux/suspend.h>
15 /* Cannon Lake: PGD PFET Enable Ack Status Register(s) bitmap */
16 const struct pmc_bit_map cnp_pfear_map
[] = {
50 {"CSME_CLINK", BIT(6)},
51 {"CSME_PTIO", BIT(7)},
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)},
68 {"CSME_PECI", BIT(6)},
91 const struct pmc_bit_map
*ext_cnp_pfear_map
[] = {
93 * Check intel_pmc_core_ids[] users of cnp_reg_map for
94 * a list of core SoCs using this.
100 const struct pmc_bit_map cnp_slps0_dbg0_map
[] = {
101 {"AUDIO_D3", BIT(0)},
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)},
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)},
149 const struct pmc_bit_map
*cnp_slps0_dbg_maps
[] = {
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
},
179 * Check intel_pmc_core_ids[] users of cnp_reg_map for
180 * a list of core SoCs using this.
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
},
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
,
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
,
211 * Disable C1 auto-demotion
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.
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.
223 static DEFINE_PER_CPU(u64
, pkg_cst_config
);
225 static void disable_c1_auto_demote(void *unused
)
227 int cpunum
= smp_processor_id();
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
);
235 pr_debug("%s: cpu:%d cst %llx\n", __func__
, cpunum
, val
);
238 static void restore_c1_auto_demote(void *unused
)
240 int cpunum
= smp_processor_id();
242 wrmsrl(MSR_PKG_CST_CONFIG_CONTROL
, per_cpu(pkg_cst_config
, cpunum
));
244 pr_debug("%s: cpu:%d cst %llx\n", __func__
, cpunum
,
245 per_cpu(pkg_cst_config
, cpunum
));
248 static void s2idle_cpu_quirk(smp_call_func_t func
)
250 if (pm_suspend_via_firmware())
253 on_each_cpu(func
, NULL
, true);
256 void cnl_suspend(struct pmc_dev
*pmcdev
)
258 s2idle_cpu_quirk(disable_c1_auto_demote
);
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.
265 pmc_core_send_ltr_ignore(pmcdev
, 3, 1);
268 int cnl_resume(struct pmc_dev
*pmcdev
)
270 s2idle_cpu_quirk(restore_c1_auto_demote
);
272 pmc_core_send_ltr_ignore(pmcdev
, 3, 0);
274 return pmc_core_resume_common(pmcdev
);
277 int cnp_core_init(struct pmc_dev
*pmcdev
)
279 struct pmc
*pmc
= pmcdev
->pmcs
[PMC_IDX_MAIN
];
282 pmcdev
->suspend
= cnl_suspend
;
283 pmcdev
->resume
= cnl_resume
;
285 pmc
->map
= &cnp_reg_map
;
286 ret
= get_primary_reg_base(pmc
);
290 pmc_core_get_low_power_modes(pmcdev
);