]> Git Repo - J-linux.git/blob - drivers/platform/x86/intel/pmc/cnp.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / platform / x86 / intel / pmc / cnp.c
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
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
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
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
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
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
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 }
This page took 0.043874 seconds and 4 git commands to generate.