1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Intel Atom SoC Power Management Controller Driver |
4 | * Copyright (c) 2014-2015,2017,2022 Intel Corporation. |
5 | */ |
6 | |
7 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
8 | |
9 | #include <linux/acpi.h> |
10 | #include <linux/debugfs.h> |
11 | #include <linux/device.h> |
12 | #include <linux/dmi.h> |
13 | #include <linux/init.h> |
14 | #include <linux/io.h> |
15 | #include <linux/platform_data/x86/clk-pmc-atom.h> |
16 | #include <linux/platform_data/x86/pmc_atom.h> |
17 | #include <linux/platform_data/x86/simatic-ipc.h> |
18 | #include <linux/platform_device.h> |
19 | #include <linux/pci.h> |
20 | #include <linux/seq_file.h> |
21 | #include <linux/suspend.h> |
22 | |
23 | struct pmc_bit_map { |
24 | const char *name; |
25 | u32 bit_mask; |
26 | }; |
27 | |
28 | struct pmc_reg_map { |
29 | const struct pmc_bit_map *d3_sts_0; |
30 | const struct pmc_bit_map *d3_sts_1; |
31 | const struct pmc_bit_map *func_dis; |
32 | const struct pmc_bit_map *func_dis_2; |
33 | const struct pmc_bit_map *pss; |
34 | }; |
35 | |
36 | struct pmc_data { |
37 | const struct pmc_reg_map *map; |
38 | const struct pmc_clk *clks; |
39 | }; |
40 | |
41 | struct pmc_dev { |
42 | u32 base_addr; |
43 | void __iomem *regmap; |
44 | const struct pmc_reg_map *map; |
45 | #ifdef CONFIG_DEBUG_FS |
46 | struct dentry *dbgfs_dir; |
47 | #endif /* CONFIG_DEBUG_FS */ |
48 | bool init; |
49 | }; |
50 | |
51 | static struct pmc_dev pmc_device; |
52 | static u32 acpi_base_addr; |
53 | |
54 | static const struct pmc_clk byt_clks[] = { |
55 | { |
56 | .name = "xtal" , |
57 | .freq = 25000000, |
58 | .parent_name = NULL, |
59 | }, |
60 | { |
61 | .name = "pll" , |
62 | .freq = 19200000, |
63 | .parent_name = "xtal" , |
64 | }, |
65 | {} |
66 | }; |
67 | |
68 | static const struct pmc_clk cht_clks[] = { |
69 | { |
70 | .name = "xtal" , |
71 | .freq = 19200000, |
72 | .parent_name = NULL, |
73 | }, |
74 | {} |
75 | }; |
76 | |
77 | static const struct pmc_bit_map d3_sts_0_map[] = { |
78 | {"LPSS1_F0_DMA" , BIT_LPSS1_F0_DMA}, |
79 | {"LPSS1_F1_PWM1" , BIT_LPSS1_F1_PWM1}, |
80 | {"LPSS1_F2_PWM2" , BIT_LPSS1_F2_PWM2}, |
81 | {"LPSS1_F3_HSUART1" , BIT_LPSS1_F3_HSUART1}, |
82 | {"LPSS1_F4_HSUART2" , BIT_LPSS1_F4_HSUART2}, |
83 | {"LPSS1_F5_SPI" , BIT_LPSS1_F5_SPI}, |
84 | {"LPSS1_F6_Reserved" , BIT_LPSS1_F6_XXX}, |
85 | {"LPSS1_F7_Reserved" , BIT_LPSS1_F7_XXX}, |
86 | {"SCC_EMMC" , BIT_SCC_EMMC}, |
87 | {"SCC_SDIO" , BIT_SCC_SDIO}, |
88 | {"SCC_SDCARD" , BIT_SCC_SDCARD}, |
89 | {"SCC_MIPI" , BIT_SCC_MIPI}, |
90 | {"HDA" , BIT_HDA}, |
91 | {"LPE" , BIT_LPE}, |
92 | {"OTG" , BIT_OTG}, |
93 | {"USH" , BIT_USH}, |
94 | {"GBE" , BIT_GBE}, |
95 | {"SATA" , BIT_SATA}, |
96 | {"USB_EHCI" , BIT_USB_EHCI}, |
97 | {"SEC" , BIT_SEC}, |
98 | {"PCIE_PORT0" , BIT_PCIE_PORT0}, |
99 | {"PCIE_PORT1" , BIT_PCIE_PORT1}, |
100 | {"PCIE_PORT2" , BIT_PCIE_PORT2}, |
101 | {"PCIE_PORT3" , BIT_PCIE_PORT3}, |
102 | {"LPSS2_F0_DMA" , BIT_LPSS2_F0_DMA}, |
103 | {"LPSS2_F1_I2C1" , BIT_LPSS2_F1_I2C1}, |
104 | {"LPSS2_F2_I2C2" , BIT_LPSS2_F2_I2C2}, |
105 | {"LPSS2_F3_I2C3" , BIT_LPSS2_F3_I2C3}, |
106 | {"LPSS2_F3_I2C4" , BIT_LPSS2_F4_I2C4}, |
107 | {"LPSS2_F5_I2C5" , BIT_LPSS2_F5_I2C5}, |
108 | {"LPSS2_F6_I2C6" , BIT_LPSS2_F6_I2C6}, |
109 | {"LPSS2_F7_I2C7" , BIT_LPSS2_F7_I2C7}, |
110 | {} |
111 | }; |
112 | |
113 | static struct pmc_bit_map byt_d3_sts_1_map[] = { |
114 | {"SMB" , BIT_SMB}, |
115 | {"OTG_SS_PHY" , BIT_OTG_SS_PHY}, |
116 | {"USH_SS_PHY" , BIT_USH_SS_PHY}, |
117 | {"DFX" , BIT_DFX}, |
118 | {} |
119 | }; |
120 | |
121 | static struct pmc_bit_map cht_d3_sts_1_map[] = { |
122 | {"SMB" , BIT_SMB}, |
123 | {"GMM" , BIT_STS_GMM}, |
124 | {"ISH" , BIT_STS_ISH}, |
125 | {} |
126 | }; |
127 | |
128 | static struct pmc_bit_map cht_func_dis_2_map[] = { |
129 | {"SMB" , BIT_SMB}, |
130 | {"GMM" , BIT_FD_GMM}, |
131 | {"ISH" , BIT_FD_ISH}, |
132 | {} |
133 | }; |
134 | |
135 | static const struct pmc_bit_map byt_pss_map[] = { |
136 | {"GBE" , PMC_PSS_BIT_GBE}, |
137 | {"SATA" , PMC_PSS_BIT_SATA}, |
138 | {"HDA" , PMC_PSS_BIT_HDA}, |
139 | {"SEC" , PMC_PSS_BIT_SEC}, |
140 | {"PCIE" , PMC_PSS_BIT_PCIE}, |
141 | {"LPSS" , PMC_PSS_BIT_LPSS}, |
142 | {"LPE" , PMC_PSS_BIT_LPE}, |
143 | {"DFX" , PMC_PSS_BIT_DFX}, |
144 | {"USH_CTRL" , PMC_PSS_BIT_USH_CTRL}, |
145 | {"USH_SUS" , PMC_PSS_BIT_USH_SUS}, |
146 | {"USH_VCCS" , PMC_PSS_BIT_USH_VCCS}, |
147 | {"USH_VCCA" , PMC_PSS_BIT_USH_VCCA}, |
148 | {"OTG_CTRL" , PMC_PSS_BIT_OTG_CTRL}, |
149 | {"OTG_VCCS" , PMC_PSS_BIT_OTG_VCCS}, |
150 | {"OTG_VCCA_CLK" , PMC_PSS_BIT_OTG_VCCA_CLK}, |
151 | {"OTG_VCCA" , PMC_PSS_BIT_OTG_VCCA}, |
152 | {"USB" , PMC_PSS_BIT_USB}, |
153 | {"USB_SUS" , PMC_PSS_BIT_USB_SUS}, |
154 | {} |
155 | }; |
156 | |
157 | static const struct pmc_bit_map cht_pss_map[] = { |
158 | {"SATA" , PMC_PSS_BIT_SATA}, |
159 | {"HDA" , PMC_PSS_BIT_HDA}, |
160 | {"SEC" , PMC_PSS_BIT_SEC}, |
161 | {"PCIE" , PMC_PSS_BIT_PCIE}, |
162 | {"LPSS" , PMC_PSS_BIT_LPSS}, |
163 | {"LPE" , PMC_PSS_BIT_LPE}, |
164 | {"UFS" , PMC_PSS_BIT_CHT_UFS}, |
165 | {"UXD" , PMC_PSS_BIT_CHT_UXD}, |
166 | {"UXD_FD" , PMC_PSS_BIT_CHT_UXD_FD}, |
167 | {"UX_ENG" , PMC_PSS_BIT_CHT_UX_ENG}, |
168 | {"USB_SUS" , PMC_PSS_BIT_CHT_USB_SUS}, |
169 | {"GMM" , PMC_PSS_BIT_CHT_GMM}, |
170 | {"ISH" , PMC_PSS_BIT_CHT_ISH}, |
171 | {"DFX_MASTER" , PMC_PSS_BIT_CHT_DFX_MASTER}, |
172 | {"DFX_CLUSTER1" , PMC_PSS_BIT_CHT_DFX_CLUSTER1}, |
173 | {"DFX_CLUSTER2" , PMC_PSS_BIT_CHT_DFX_CLUSTER2}, |
174 | {"DFX_CLUSTER3" , PMC_PSS_BIT_CHT_DFX_CLUSTER3}, |
175 | {"DFX_CLUSTER4" , PMC_PSS_BIT_CHT_DFX_CLUSTER4}, |
176 | {"DFX_CLUSTER5" , PMC_PSS_BIT_CHT_DFX_CLUSTER5}, |
177 | {} |
178 | }; |
179 | |
180 | static const struct pmc_reg_map byt_reg_map = { |
181 | .d3_sts_0 = d3_sts_0_map, |
182 | .d3_sts_1 = byt_d3_sts_1_map, |
183 | .func_dis = d3_sts_0_map, |
184 | .func_dis_2 = byt_d3_sts_1_map, |
185 | .pss = byt_pss_map, |
186 | }; |
187 | |
188 | static const struct pmc_reg_map cht_reg_map = { |
189 | .d3_sts_0 = d3_sts_0_map, |
190 | .d3_sts_1 = cht_d3_sts_1_map, |
191 | .func_dis = d3_sts_0_map, |
192 | .func_dis_2 = cht_func_dis_2_map, |
193 | .pss = cht_pss_map, |
194 | }; |
195 | |
196 | static const struct pmc_data byt_data = { |
197 | .map = &byt_reg_map, |
198 | .clks = byt_clks, |
199 | }; |
200 | |
201 | static const struct pmc_data cht_data = { |
202 | .map = &cht_reg_map, |
203 | .clks = cht_clks, |
204 | }; |
205 | |
206 | static inline u32 pmc_reg_read(struct pmc_dev *pmc, int reg_offset) |
207 | { |
208 | return readl(addr: pmc->regmap + reg_offset); |
209 | } |
210 | |
211 | static inline void pmc_reg_write(struct pmc_dev *pmc, int reg_offset, u32 val) |
212 | { |
213 | writel(val, addr: pmc->regmap + reg_offset); |
214 | } |
215 | |
216 | int pmc_atom_read(int offset, u32 *value) |
217 | { |
218 | struct pmc_dev *pmc = &pmc_device; |
219 | |
220 | if (!pmc->init) |
221 | return -ENODEV; |
222 | |
223 | *value = pmc_reg_read(pmc, reg_offset: offset); |
224 | return 0; |
225 | } |
226 | |
227 | static void pmc_power_off(void) |
228 | { |
229 | u16 pm1_cnt_port; |
230 | u32 pm1_cnt_value; |
231 | |
232 | pr_info("Preparing to enter system sleep state S5\n" ); |
233 | |
234 | pm1_cnt_port = acpi_base_addr + PM1_CNT; |
235 | |
236 | pm1_cnt_value = inl(port: pm1_cnt_port); |
237 | pm1_cnt_value &= ~SLEEP_TYPE_MASK; |
238 | pm1_cnt_value |= SLEEP_TYPE_S5; |
239 | pm1_cnt_value |= SLEEP_ENABLE; |
240 | |
241 | outl(value: pm1_cnt_value, port: pm1_cnt_port); |
242 | } |
243 | |
244 | static void pmc_hw_reg_setup(struct pmc_dev *pmc) |
245 | { |
246 | /* |
247 | * Disable PMC S0IX_WAKE_EN events coming from: |
248 | * - LPC clock run |
249 | * - GPIO_SUS ored dedicated IRQs |
250 | * - GPIO_SCORE ored dedicated IRQs |
251 | * - GPIO_SUS shared IRQ |
252 | * - GPIO_SCORE shared IRQ |
253 | */ |
254 | pmc_reg_write(pmc, PMC_S0IX_WAKE_EN, val: (u32)PMC_WAKE_EN_SETTING); |
255 | } |
256 | |
257 | #ifdef CONFIG_DEBUG_FS |
258 | static void pmc_dev_state_print(struct seq_file *s, int reg_index, |
259 | u32 sts, const struct pmc_bit_map *sts_map, |
260 | u32 fd, const struct pmc_bit_map *fd_map) |
261 | { |
262 | int offset = PMC_REG_BIT_WIDTH * reg_index; |
263 | int index; |
264 | |
265 | for (index = 0; sts_map[index].name; index++) { |
266 | seq_printf(m: s, fmt: "Dev: %-2d - %-32s\tState: %s [%s]\n" , |
267 | offset + index, sts_map[index].name, |
268 | fd_map[index].bit_mask & fd ? "Disabled" : "Enabled " , |
269 | sts_map[index].bit_mask & sts ? "D3" : "D0" ); |
270 | } |
271 | } |
272 | |
273 | static int pmc_dev_state_show(struct seq_file *s, void *unused) |
274 | { |
275 | struct pmc_dev *pmc = s->private; |
276 | const struct pmc_reg_map *m = pmc->map; |
277 | u32 func_dis, func_dis_2; |
278 | u32 d3_sts_0, d3_sts_1; |
279 | |
280 | func_dis = pmc_reg_read(pmc, PMC_FUNC_DIS); |
281 | func_dis_2 = pmc_reg_read(pmc, PMC_FUNC_DIS_2); |
282 | d3_sts_0 = pmc_reg_read(pmc, PMC_D3_STS_0); |
283 | d3_sts_1 = pmc_reg_read(pmc, PMC_D3_STS_1); |
284 | |
285 | /* Low part */ |
286 | pmc_dev_state_print(s, reg_index: 0, sts: d3_sts_0, sts_map: m->d3_sts_0, fd: func_dis, fd_map: m->func_dis); |
287 | |
288 | /* High part */ |
289 | pmc_dev_state_print(s, reg_index: 1, sts: d3_sts_1, sts_map: m->d3_sts_1, fd: func_dis_2, fd_map: m->func_dis_2); |
290 | |
291 | return 0; |
292 | } |
293 | |
294 | DEFINE_SHOW_ATTRIBUTE(pmc_dev_state); |
295 | |
296 | static int pmc_pss_state_show(struct seq_file *s, void *unused) |
297 | { |
298 | struct pmc_dev *pmc = s->private; |
299 | const struct pmc_bit_map *map = pmc->map->pss; |
300 | u32 pss = pmc_reg_read(pmc, PMC_PSS); |
301 | int index; |
302 | |
303 | for (index = 0; map[index].name; index++) { |
304 | seq_printf(m: s, fmt: "Island: %-2d - %-32s\tState: %s\n" , |
305 | index, map[index].name, |
306 | map[index].bit_mask & pss ? "Off" : "On" ); |
307 | } |
308 | return 0; |
309 | } |
310 | |
311 | DEFINE_SHOW_ATTRIBUTE(pmc_pss_state); |
312 | |
313 | static int pmc_sleep_tmr_show(struct seq_file *s, void *unused) |
314 | { |
315 | struct pmc_dev *pmc = s->private; |
316 | u64 s0ir_tmr, s0i1_tmr, s0i2_tmr, s0i3_tmr, s0_tmr; |
317 | |
318 | s0ir_tmr = (u64)pmc_reg_read(pmc, PMC_S0IR_TMR) << PMC_TMR_SHIFT; |
319 | s0i1_tmr = (u64)pmc_reg_read(pmc, PMC_S0I1_TMR) << PMC_TMR_SHIFT; |
320 | s0i2_tmr = (u64)pmc_reg_read(pmc, PMC_S0I2_TMR) << PMC_TMR_SHIFT; |
321 | s0i3_tmr = (u64)pmc_reg_read(pmc, PMC_S0I3_TMR) << PMC_TMR_SHIFT; |
322 | s0_tmr = (u64)pmc_reg_read(pmc, PMC_S0_TMR) << PMC_TMR_SHIFT; |
323 | |
324 | seq_printf(m: s, fmt: "S0IR Residency:\t%lldus\n" , s0ir_tmr); |
325 | seq_printf(m: s, fmt: "S0I1 Residency:\t%lldus\n" , s0i1_tmr); |
326 | seq_printf(m: s, fmt: "S0I2 Residency:\t%lldus\n" , s0i2_tmr); |
327 | seq_printf(m: s, fmt: "S0I3 Residency:\t%lldus\n" , s0i3_tmr); |
328 | seq_printf(m: s, fmt: "S0 Residency:\t%lldus\n" , s0_tmr); |
329 | return 0; |
330 | } |
331 | |
332 | DEFINE_SHOW_ATTRIBUTE(pmc_sleep_tmr); |
333 | |
334 | static void pmc_dbgfs_register(struct pmc_dev *pmc) |
335 | { |
336 | struct dentry *dir; |
337 | |
338 | dir = debugfs_create_dir(name: "pmc_atom" , NULL); |
339 | |
340 | pmc->dbgfs_dir = dir; |
341 | |
342 | debugfs_create_file(name: "dev_state" , S_IFREG | S_IRUGO, parent: dir, data: pmc, |
343 | fops: &pmc_dev_state_fops); |
344 | debugfs_create_file(name: "pss_state" , S_IFREG | S_IRUGO, parent: dir, data: pmc, |
345 | fops: &pmc_pss_state_fops); |
346 | debugfs_create_file(name: "sleep_state" , S_IFREG | S_IRUGO, parent: dir, data: pmc, |
347 | fops: &pmc_sleep_tmr_fops); |
348 | } |
349 | #else |
350 | static void pmc_dbgfs_register(struct pmc_dev *pmc) |
351 | { |
352 | } |
353 | #endif /* CONFIG_DEBUG_FS */ |
354 | |
355 | static bool pmc_clk_is_critical = true; |
356 | |
357 | static int dmi_callback(const struct dmi_system_id *d) |
358 | { |
359 | pr_info("%s: PMC critical clocks quirk enabled\n" , d->ident); |
360 | |
361 | return 1; |
362 | } |
363 | |
364 | static int dmi_callback_siemens(const struct dmi_system_id *d) |
365 | { |
366 | u32 st_id; |
367 | |
368 | if (dmi_walk(decode: simatic_ipc_find_dmi_entry_helper, private_data: &st_id)) |
369 | goto out; |
370 | |
371 | if (st_id == SIMATIC_IPC_IPC227E || st_id == SIMATIC_IPC_IPC277E) |
372 | return dmi_callback(d); |
373 | |
374 | out: |
375 | pmc_clk_is_critical = false; |
376 | return 1; |
377 | } |
378 | |
379 | /* |
380 | * Some systems need one or more of their pmc_plt_clks to be |
381 | * marked as critical. |
382 | */ |
383 | static const struct dmi_system_id critclk_systems[] = { |
384 | { |
385 | /* pmc_plt_clk0 is used for an external HSIC USB HUB */ |
386 | .ident = "MPL CEC1x" , |
387 | .callback = dmi_callback, |
388 | .matches = { |
389 | DMI_MATCH(DMI_SYS_VENDOR, "MPL AG" ), |
390 | DMI_MATCH(DMI_PRODUCT_NAME, "CEC10 Family" ), |
391 | }, |
392 | }, |
393 | { |
394 | /* |
395 | * Lex System / Lex Computech Co. makes a lot of Bay Trail |
396 | * based embedded boards which often come with multiple |
397 | * ethernet controllers using multiple pmc_plt_clks. See: |
398 | * https://www.lex.com.tw/products/embedded-ipc-board/ |
399 | */ |
400 | .ident = "Lex BayTrail" , |
401 | .callback = dmi_callback, |
402 | .matches = { |
403 | DMI_MATCH(DMI_SYS_VENDOR, "Lex BayTrail" ), |
404 | }, |
405 | }, |
406 | { |
407 | /* pmc_plt_clk* - are used for ethernet controllers */ |
408 | .ident = "Beckhoff Baytrail" , |
409 | .callback = dmi_callback, |
410 | .matches = { |
411 | DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation" ), |
412 | DMI_MATCH(DMI_PRODUCT_FAMILY, "CBxx63" ), |
413 | }, |
414 | }, |
415 | { |
416 | .ident = "SIEMENS AG" , |
417 | .callback = dmi_callback_siemens, |
418 | .matches = { |
419 | DMI_MATCH(DMI_SYS_VENDOR, "SIEMENS AG" ), |
420 | }, |
421 | }, |
422 | {} |
423 | }; |
424 | |
425 | static int pmc_setup_clks(struct pci_dev *pdev, void __iomem *pmc_regmap, |
426 | const struct pmc_data *pmc_data) |
427 | { |
428 | struct platform_device *clkdev; |
429 | struct pmc_clk_data *clk_data; |
430 | |
431 | clk_data = kzalloc(size: sizeof(*clk_data), GFP_KERNEL); |
432 | if (!clk_data) |
433 | return -ENOMEM; |
434 | |
435 | clk_data->base = pmc_regmap; /* offset is added by client */ |
436 | clk_data->clks = pmc_data->clks; |
437 | if (dmi_check_system(list: critclk_systems)) |
438 | clk_data->critical = pmc_clk_is_critical; |
439 | |
440 | clkdev = platform_device_register_data(parent: &pdev->dev, name: "clk-pmc-atom" , |
441 | PLATFORM_DEVID_NONE, |
442 | data: clk_data, size: sizeof(*clk_data)); |
443 | if (IS_ERR(ptr: clkdev)) { |
444 | kfree(objp: clk_data); |
445 | return PTR_ERR(ptr: clkdev); |
446 | } |
447 | |
448 | kfree(objp: clk_data); |
449 | |
450 | return 0; |
451 | } |
452 | |
453 | #ifdef CONFIG_SUSPEND |
454 | static void pmc_dev_state_check(u32 sts, const struct pmc_bit_map *sts_map, |
455 | u32 fd, const struct pmc_bit_map *fd_map, |
456 | u32 sts_possible_false_pos) |
457 | { |
458 | int index; |
459 | |
460 | for (index = 0; sts_map[index].name; index++) { |
461 | if (!(fd_map[index].bit_mask & fd) && |
462 | !(sts_map[index].bit_mask & sts)) { |
463 | if (sts_map[index].bit_mask & sts_possible_false_pos) |
464 | pm_pr_dbg("%s is in D0 prior to s2idle\n" , |
465 | sts_map[index].name); |
466 | else |
467 | pr_err("%s is in D0 prior to s2idle\n" , |
468 | sts_map[index].name); |
469 | } |
470 | } |
471 | } |
472 | |
473 | static void pmc_s2idle_check(void) |
474 | { |
475 | struct pmc_dev *pmc = &pmc_device; |
476 | const struct pmc_reg_map *m = pmc->map; |
477 | u32 func_dis, func_dis_2; |
478 | u32 d3_sts_0, d3_sts_1; |
479 | u32 false_pos_sts_0, false_pos_sts_1; |
480 | int i; |
481 | |
482 | func_dis = pmc_reg_read(pmc, PMC_FUNC_DIS); |
483 | func_dis_2 = pmc_reg_read(pmc, PMC_FUNC_DIS_2); |
484 | d3_sts_0 = pmc_reg_read(pmc, PMC_D3_STS_0); |
485 | d3_sts_1 = pmc_reg_read(pmc, PMC_D3_STS_1); |
486 | |
487 | /* |
488 | * Some blocks are not used on lower-featured versions of the SoC and |
489 | * always report D0, add these to false_pos mask to log at debug level. |
490 | */ |
491 | if (m->d3_sts_1 == byt_d3_sts_1_map) { |
492 | /* Bay Trail */ |
493 | false_pos_sts_0 = BIT_GBE | BIT_SATA | BIT_PCIE_PORT0 | |
494 | BIT_PCIE_PORT1 | BIT_PCIE_PORT2 | BIT_PCIE_PORT3 | |
495 | BIT_LPSS2_F5_I2C5; |
496 | false_pos_sts_1 = BIT_SMB | BIT_USH_SS_PHY | BIT_DFX; |
497 | } else { |
498 | /* Cherry Trail */ |
499 | false_pos_sts_0 = BIT_GBE | BIT_SATA | BIT_LPSS2_F7_I2C7; |
500 | false_pos_sts_1 = BIT_SMB | BIT_STS_ISH; |
501 | } |
502 | |
503 | pmc_dev_state_check(sts: d3_sts_0, sts_map: m->d3_sts_0, fd: func_dis, fd_map: m->func_dis, sts_possible_false_pos: false_pos_sts_0); |
504 | pmc_dev_state_check(sts: d3_sts_1, sts_map: m->d3_sts_1, fd: func_dis_2, fd_map: m->func_dis_2, sts_possible_false_pos: false_pos_sts_1); |
505 | |
506 | /* Forced-on PMC clocks prevent S0i3 */ |
507 | for (i = 0; i < PMC_CLK_NUM; i++) { |
508 | u32 ctl = pmc_reg_read(pmc, PMC_CLK_CTL_OFFSET + 4 * i); |
509 | |
510 | if ((ctl & PMC_MASK_CLK_CTL) != PMC_CLK_CTL_FORCE_ON) |
511 | continue; |
512 | |
513 | pr_err("clock %d is ON prior to freeze (ctl 0x%08x)\n" , i, ctl); |
514 | } |
515 | } |
516 | |
517 | static struct acpi_s2idle_dev_ops pmc_s2idle_ops = { |
518 | .check = pmc_s2idle_check, |
519 | }; |
520 | |
521 | static void pmc_s2idle_check_register(void) |
522 | { |
523 | acpi_register_lps0_dev(arg: &pmc_s2idle_ops); |
524 | } |
525 | #else |
526 | static void pmc_s2idle_check_register(void) {} |
527 | #endif |
528 | |
529 | static int pmc_setup_dev(struct pci_dev *pdev, const struct pci_device_id *ent) |
530 | { |
531 | struct pmc_dev *pmc = &pmc_device; |
532 | const struct pmc_data *data = (struct pmc_data *)ent->driver_data; |
533 | const struct pmc_reg_map *map = data->map; |
534 | int ret; |
535 | |
536 | /* Obtain ACPI base address */ |
537 | pci_read_config_dword(dev: pdev, ACPI_BASE_ADDR_OFFSET, val: &acpi_base_addr); |
538 | acpi_base_addr &= ACPI_BASE_ADDR_MASK; |
539 | |
540 | /* Install power off function */ |
541 | if (acpi_base_addr != 0 && pm_power_off == NULL) |
542 | pm_power_off = pmc_power_off; |
543 | |
544 | pci_read_config_dword(dev: pdev, PMC_BASE_ADDR_OFFSET, val: &pmc->base_addr); |
545 | pmc->base_addr &= PMC_BASE_ADDR_MASK; |
546 | |
547 | pmc->regmap = ioremap(offset: pmc->base_addr, PMC_MMIO_REG_LEN); |
548 | if (!pmc->regmap) { |
549 | dev_err(&pdev->dev, "error: ioremap failed\n" ); |
550 | return -ENOMEM; |
551 | } |
552 | |
553 | pmc->map = map; |
554 | |
555 | /* PMC hardware registers setup */ |
556 | pmc_hw_reg_setup(pmc); |
557 | |
558 | pmc_dbgfs_register(pmc); |
559 | |
560 | /* Register platform clocks - PMC_PLT_CLK [0..5] */ |
561 | ret = pmc_setup_clks(pdev, pmc_regmap: pmc->regmap, pmc_data: data); |
562 | if (ret) |
563 | dev_warn(&pdev->dev, "platform clocks register failed: %d\n" , |
564 | ret); |
565 | |
566 | pmc_s2idle_check_register(); |
567 | pmc->init = true; |
568 | return ret; |
569 | } |
570 | |
571 | /* Data for PCI driver interface used by pci_match_id() call below */ |
572 | static const struct pci_device_id pmc_pci_ids[] = { |
573 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_VLV_PMC), (kernel_ulong_t)&byt_data }, |
574 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_CHT_PMC), (kernel_ulong_t)&cht_data }, |
575 | {} |
576 | }; |
577 | |
578 | static int __init pmc_atom_init(void) |
579 | { |
580 | struct pci_dev *pdev = NULL; |
581 | const struct pci_device_id *ent; |
582 | |
583 | /* |
584 | * We look for our device - PCU PMC. |
585 | * We assume that there is maximum one device. |
586 | * |
587 | * We can't use plain pci_driver mechanism, |
588 | * as the device is really a multiple function device, |
589 | * main driver that binds to the pci_device is lpc_ich |
590 | * and have to find & bind to the device this way. |
591 | */ |
592 | for_each_pci_dev(pdev) { |
593 | ent = pci_match_id(ids: pmc_pci_ids, dev: pdev); |
594 | if (ent) |
595 | return pmc_setup_dev(pdev, ent); |
596 | } |
597 | /* Device not found */ |
598 | return -ENODEV; |
599 | } |
600 | |
601 | device_initcall(pmc_atom_init); |
602 | |
603 | /* |
604 | MODULE_AUTHOR("Aubrey Li <aubrey.li@linux.intel.com>"); |
605 | MODULE_DESCRIPTION("Intel Atom SoC Power Management Controller Interface"); |
606 | MODULE_LICENSE("GPL v2"); |
607 | */ |
608 | |