1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * This file contains platform specific structure definitions
4 * and init function used by Tiger Lake PCH.
5 *
6 * Copyright (c) 2022, Intel Corporation.
7 * All Rights Reserved.
8 *
9 */
10
11 #include "core.h"
12
13 #define ACPI_S0IX_DSM_UUID "57a6512e-3979-4e9d-9708-ff13b2508972"
14 #define ACPI_GET_LOW_MODE_REGISTERS 1
15
16 enum pch_type {
17 PCH_H,
18 PCH_LP
19 };
20
21 const struct pmc_bit_map tgl_pfear_map[] = {
22 {"PSF9", BIT(0)},
23 {"RES_66", BIT(1)},
24 {"RES_67", BIT(2)},
25 {"RES_68", BIT(3)},
26 {"RES_69", BIT(4)},
27 {"RES_70", BIT(5)},
28 {"TBTLSX", BIT(6)},
29 {}
30 };
31
32 const struct pmc_bit_map *ext_tgl_pfear_map[] = {
33 /*
34 * Check intel_pmc_core_ids[] users of tgl_reg_map for
35 * a list of core SoCs using this.
36 */
37 cnp_pfear_map,
38 tgl_pfear_map,
39 NULL
40 };
41
42 const struct pmc_bit_map tgl_clocksource_status_map[] = {
43 {"USB2PLL_OFF_STS", BIT(18)},
44 {"PCIe/USB3.1_Gen2PLL_OFF_STS", BIT(19)},
45 {"PCIe_Gen3PLL_OFF_STS", BIT(20)},
46 {"OPIOPLL_OFF_STS", BIT(21)},
47 {"OCPLL_OFF_STS", BIT(22)},
48 {"MainPLL_OFF_STS", BIT(23)},
49 {"MIPIPLL_OFF_STS", BIT(24)},
50 {"Fast_XTAL_Osc_OFF_STS", BIT(25)},
51 {"AC_Ring_Osc_OFF_STS", BIT(26)},
52 {"MC_Ring_Osc_OFF_STS", BIT(27)},
53 {"SATAPLL_OFF_STS", BIT(29)},
54 {"XTAL_USB2PLL_OFF_STS", BIT(31)},
55 {}
56 };
57
58 const struct pmc_bit_map tgl_power_gating_status_map[] = {
59 {"CSME_PG_STS", BIT(0)},
60 {"SATA_PG_STS", BIT(1)},
61 {"xHCI_PG_STS", BIT(2)},
62 {"UFSX2_PG_STS", BIT(3)},
63 {"OTG_PG_STS", BIT(5)},
64 {"SPA_PG_STS", BIT(6)},
65 {"SPB_PG_STS", BIT(7)},
66 {"SPC_PG_STS", BIT(8)},
67 {"SPD_PG_STS", BIT(9)},
68 {"SPE_PG_STS", BIT(10)},
69 {"SPF_PG_STS", BIT(11)},
70 {"LSX_PG_STS", BIT(13)},
71 {"P2SB_PG_STS", BIT(14)},
72 {"PSF_PG_STS", BIT(15)},
73 {"SBR_PG_STS", BIT(16)},
74 {"OPIDMI_PG_STS", BIT(17)},
75 {"THC0_PG_STS", BIT(18)},
76 {"THC1_PG_STS", BIT(19)},
77 {"GBETSN_PG_STS", BIT(20)},
78 {"GBE_PG_STS", BIT(21)},
79 {"LPSS_PG_STS", BIT(22)},
80 {"MMP_UFSX2_PG_STS", BIT(23)},
81 {"MMP_UFSX2B_PG_STS", BIT(24)},
82 {"FIA_PG_STS", BIT(25)},
83 {}
84 };
85
86 const struct pmc_bit_map tgl_d3_status_map[] = {
87 {"ADSP_D3_STS", BIT(0)},
88 {"SATA_D3_STS", BIT(1)},
89 {"xHCI0_D3_STS", BIT(2)},
90 {"xDCI1_D3_STS", BIT(5)},
91 {"SDX_D3_STS", BIT(6)},
92 {"EMMC_D3_STS", BIT(7)},
93 {"IS_D3_STS", BIT(8)},
94 {"THC0_D3_STS", BIT(9)},
95 {"THC1_D3_STS", BIT(10)},
96 {"GBE_D3_STS", BIT(11)},
97 {"GBE_TSN_D3_STS", BIT(12)},
98 {}
99 };
100
101 const struct pmc_bit_map tgl_vnn_req_status_map[] = {
102 {"GPIO_COM0_VNN_REQ_STS", BIT(1)},
103 {"GPIO_COM1_VNN_REQ_STS", BIT(2)},
104 {"GPIO_COM2_VNN_REQ_STS", BIT(3)},
105 {"GPIO_COM3_VNN_REQ_STS", BIT(4)},
106 {"GPIO_COM4_VNN_REQ_STS", BIT(5)},
107 {"GPIO_COM5_VNN_REQ_STS", BIT(6)},
108 {"Audio_VNN_REQ_STS", BIT(7)},
109 {"ISH_VNN_REQ_STS", BIT(8)},
110 {"CNVI_VNN_REQ_STS", BIT(9)},
111 {"eSPI_VNN_REQ_STS", BIT(10)},
112 {"Display_VNN_REQ_STS", BIT(11)},
113 {"DTS_VNN_REQ_STS", BIT(12)},
114 {"SMBUS_VNN_REQ_STS", BIT(14)},
115 {"CSME_VNN_REQ_STS", BIT(15)},
116 {"SMLINK0_VNN_REQ_STS", BIT(16)},
117 {"SMLINK1_VNN_REQ_STS", BIT(17)},
118 {"CLINK_VNN_REQ_STS", BIT(20)},
119 {"DCI_VNN_REQ_STS", BIT(21)},
120 {"ITH_VNN_REQ_STS", BIT(22)},
121 {"CSME_VNN_REQ_STS", BIT(24)},
122 {"GBE_VNN_REQ_STS", BIT(25)},
123 {}
124 };
125
126 const struct pmc_bit_map tgl_vnn_misc_status_map[] = {
127 {"CPU_C10_REQ_STS_0", BIT(0)},
128 {"PCIe_LPM_En_REQ_STS_3", BIT(3)},
129 {"ITH_REQ_STS_5", BIT(5)},
130 {"CNVI_REQ_STS_6", BIT(6)},
131 {"ISH_REQ_STS_7", BIT(7)},
132 {"USB2_SUS_PG_Sys_REQ_STS_10", BIT(10)},
133 {"PCIe_Clk_REQ_STS_12", BIT(12)},
134 {"MPHY_Core_DL_REQ_STS_16", BIT(16)},
135 {"Break-even_En_REQ_STS_17", BIT(17)},
136 {"Auto-demo_En_REQ_STS_18", BIT(18)},
137 {"MPHY_SUS_REQ_STS_22", BIT(22)},
138 {"xDCI_attached_REQ_STS_24", BIT(24)},
139 {}
140 };
141
142 const struct pmc_bit_map tgl_signal_status_map[] = {
143 {"LSX_Wake0_En_STS", BIT(0)},
144 {"LSX_Wake0_Pol_STS", BIT(1)},
145 {"LSX_Wake1_En_STS", BIT(2)},
146 {"LSX_Wake1_Pol_STS", BIT(3)},
147 {"LSX_Wake2_En_STS", BIT(4)},
148 {"LSX_Wake2_Pol_STS", BIT(5)},
149 {"LSX_Wake3_En_STS", BIT(6)},
150 {"LSX_Wake3_Pol_STS", BIT(7)},
151 {"LSX_Wake4_En_STS", BIT(8)},
152 {"LSX_Wake4_Pol_STS", BIT(9)},
153 {"LSX_Wake5_En_STS", BIT(10)},
154 {"LSX_Wake5_Pol_STS", BIT(11)},
155 {"LSX_Wake6_En_STS", BIT(12)},
156 {"LSX_Wake6_Pol_STS", BIT(13)},
157 {"LSX_Wake7_En_STS", BIT(14)},
158 {"LSX_Wake7_Pol_STS", BIT(15)},
159 {"Intel_Se_IO_Wake0_En_STS", BIT(16)},
160 {"Intel_Se_IO_Wake0_Pol_STS", BIT(17)},
161 {"Intel_Se_IO_Wake1_En_STS", BIT(18)},
162 {"Intel_Se_IO_Wake1_Pol_STS", BIT(19)},
163 {"Int_Timer_SS_Wake0_En_STS", BIT(20)},
164 {"Int_Timer_SS_Wake0_Pol_STS", BIT(21)},
165 {"Int_Timer_SS_Wake1_En_STS", BIT(22)},
166 {"Int_Timer_SS_Wake1_Pol_STS", BIT(23)},
167 {"Int_Timer_SS_Wake2_En_STS", BIT(24)},
168 {"Int_Timer_SS_Wake2_Pol_STS", BIT(25)},
169 {"Int_Timer_SS_Wake3_En_STS", BIT(26)},
170 {"Int_Timer_SS_Wake3_Pol_STS", BIT(27)},
171 {"Int_Timer_SS_Wake4_En_STS", BIT(28)},
172 {"Int_Timer_SS_Wake4_Pol_STS", BIT(29)},
173 {"Int_Timer_SS_Wake5_En_STS", BIT(30)},
174 {"Int_Timer_SS_Wake5_Pol_STS", BIT(31)},
175 {}
176 };
177
178 const struct pmc_bit_map *tgl_lpm_maps[] = {
179 tgl_clocksource_status_map,
180 tgl_power_gating_status_map,
181 tgl_d3_status_map,
182 tgl_vnn_req_status_map,
183 tgl_vnn_misc_status_map,
184 tgl_signal_status_map,
185 NULL
186 };
187
188 const struct pmc_reg_map tgl_reg_map = {
189 .pfear_sts = ext_tgl_pfear_map,
190 .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
191 .slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP,
192 .ltr_show_sts = cnp_ltr_show_map,
193 .msr_sts = msr_map,
194 .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
195 .regmap_length = CNP_PMC_MMIO_REG_LEN,
196 .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
197 .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES,
198 .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
199 .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
200 .ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED,
201 .lpm_num_maps = TGL_LPM_NUM_MAPS,
202 .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2,
203 .lpm_sts_latch_en_offset = TGL_LPM_STS_LATCH_EN_OFFSET,
204 .lpm_en_offset = TGL_LPM_EN_OFFSET,
205 .lpm_priority_offset = TGL_LPM_PRI_OFFSET,
206 .lpm_residency_offset = TGL_LPM_RESIDENCY_OFFSET,
207 .lpm_sts = tgl_lpm_maps,
208 .lpm_status_offset = TGL_LPM_STATUS_OFFSET,
209 .lpm_live_status_offset = TGL_LPM_LIVE_STATUS_OFFSET,
210 .etr3_offset = ETR3_OFFSET,
211 };
212
213 const struct pmc_reg_map tgl_h_reg_map = {
214 .pfear_sts = ext_tgl_pfear_map,
215 .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
216 .slp_s0_res_counter_step = TGL_PMC_SLP_S0_RES_COUNTER_STEP,
217 .ltr_show_sts = cnp_ltr_show_map,
218 .msr_sts = msr_map,
219 .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
220 .regmap_length = CNP_PMC_MMIO_REG_LEN,
221 .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
222 .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES,
223 .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
224 .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
225 .ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED,
226 .lpm_num_maps = TGL_LPM_NUM_MAPS,
227 .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2,
228 .lpm_sts_latch_en_offset = TGL_LPM_STS_LATCH_EN_OFFSET,
229 .lpm_en_offset = TGL_LPM_EN_OFFSET,
230 .lpm_priority_offset = TGL_LPM_PRI_OFFSET,
231 .lpm_residency_offset = TGL_LPM_RESIDENCY_OFFSET,
232 .lpm_sts = tgl_lpm_maps,
233 .lpm_status_offset = TGL_LPM_STATUS_OFFSET,
234 .lpm_live_status_offset = TGL_LPM_LIVE_STATUS_OFFSET,
235 .etr3_offset = ETR3_OFFSET,
236 .pson_residency_offset = TGL_PSON_RESIDENCY_OFFSET,
237 .pson_residency_counter_step = TGL_PSON_RES_COUNTER_STEP,
238 };
239
pmc_core_get_tgl_lpm_reqs(struct platform_device * pdev)240 void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev)
241 {
242 struct pmc_dev *pmcdev = platform_get_drvdata(pdev);
243 struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
244 const int num_maps = pmc->map->lpm_num_maps;
245 u32 lpm_size = LPM_MAX_NUM_MODES * num_maps * 4;
246 union acpi_object *out_obj;
247 struct acpi_device *adev;
248 guid_t s0ix_dsm_guid;
249 u32 *lpm_req_regs, *addr;
250
251 adev = ACPI_COMPANION(&pdev->dev);
252 if (!adev)
253 return;
254
255 guid_parse(ACPI_S0IX_DSM_UUID, &s0ix_dsm_guid);
256
257 out_obj = acpi_evaluate_dsm_typed(adev->handle, &s0ix_dsm_guid, 0,
258 ACPI_GET_LOW_MODE_REGISTERS, NULL, ACPI_TYPE_BUFFER);
259 if (out_obj) {
260 u32 size = out_obj->buffer.length;
261
262 if (size != lpm_size) {
263 acpi_handle_debug(adev->handle,
264 "_DSM returned unexpected buffer size, have %u, expect %u\n",
265 size, lpm_size);
266 goto free_acpi_obj;
267 }
268 } else {
269 acpi_handle_debug(adev->handle,
270 "_DSM function 0 evaluation failed\n");
271 goto free_acpi_obj;
272 }
273
274 addr = (u32 *)out_obj->buffer.pointer;
275
276 lpm_req_regs = devm_kzalloc(&pdev->dev, lpm_size * sizeof(u32),
277 GFP_KERNEL);
278 if (!lpm_req_regs)
279 goto free_acpi_obj;
280
281 memcpy(lpm_req_regs, addr, lpm_size);
282 pmc->lpm_req_regs = lpm_req_regs;
283
284 free_acpi_obj:
285 ACPI_FREE(out_obj);
286 }
287
tgl_l_core_init(struct pmc_dev * pmcdev)288 int tgl_l_core_init(struct pmc_dev *pmcdev)
289 {
290 return tgl_core_generic_init(pmcdev, PCH_LP);
291 }
292
tgl_core_init(struct pmc_dev * pmcdev)293 int tgl_core_init(struct pmc_dev *pmcdev)
294 {
295 return tgl_core_generic_init(pmcdev, PCH_H);
296 }
297
tgl_core_generic_init(struct pmc_dev * pmcdev,int pch_tp)298 int tgl_core_generic_init(struct pmc_dev *pmcdev, int pch_tp)
299 {
300 struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN];
301 int ret;
302
303 if (pch_tp == PCH_H)
304 pmc->map = &tgl_h_reg_map;
305 else
306 pmc->map = &tgl_reg_map;
307
308 pmcdev->suspend = cnl_suspend;
309 pmcdev->resume = cnl_resume;
310
311 ret = get_primary_reg_base(pmc);
312 if (ret)
313 return ret;
314
315 pmc_core_get_low_power_modes(pmcdev);
316 pmc_core_get_tgl_lpm_reqs(pmcdev->pdev);
317
318 return 0;
319 }
320