Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / drivers / platform / x86 / intel / pmc / cnp.c
blobfc5193fdf8a88acda4eae8caa752df7e9be878f2
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.
6 * Copyright (c) 2022, Intel Corporation.
7 * All Rights Reserved.
9 */
11 #include <linux/smp.h>
12 #include <linux/suspend.h>
13 #include "core.h"
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)},
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)},
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)},
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)},
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)},
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)},
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)},
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)},
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.
96 cnp_pfear_map,
97 NULL
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)},
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[] = {
150 cnp_slps0_dbg0_map,
151 cnp_slps0_dbg1_map,
152 cnp_slps0_dbg2_map,
153 NULL
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,
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,
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();
228 u64 val;
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())
251 return;
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];
280 int ret;
282 pmcdev->suspend = cnl_suspend;
283 pmcdev->resume = cnl_resume;
285 pmc->map = &cnp_reg_map;
286 ret = get_primary_reg_base(pmc);
287 if (ret)
288 return ret;
290 pmc_core_get_low_power_modes(pmcdev);
292 return 0;