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 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 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 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 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 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