2 * Intel Atom SOC Power Management Controller Driver
3 * Copyright (c) 2014, Intel Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18 #include <linux/module.h>
19 #include <linux/init.h>
20 #include <linux/pci.h>
21 #include <linux/device.h>
22 #include <linux/debugfs.h>
23 #include <linux/seq_file.h>
26 #include <asm/pmc_atom.h>
28 #define DRIVER_NAME KBUILD_MODNAME
33 #ifdef CONFIG_DEBUG_FS
34 struct dentry
*dbgfs_dir
;
35 #endif /* CONFIG_DEBUG_FS */
38 static struct pmc_dev pmc_device
;
39 static u32 acpi_base_addr
;
46 static const struct pmc_dev_map dev_map
[] = {
47 {"0 - LPSS1_F0_DMA", BIT_LPSS1_F0_DMA
},
48 {"1 - LPSS1_F1_PWM1", BIT_LPSS1_F1_PWM1
},
49 {"2 - LPSS1_F2_PWM2", BIT_LPSS1_F2_PWM2
},
50 {"3 - LPSS1_F3_HSUART1", BIT_LPSS1_F3_HSUART1
},
51 {"4 - LPSS1_F4_HSUART2", BIT_LPSS1_F4_HSUART2
},
52 {"5 - LPSS1_F5_SPI", BIT_LPSS1_F5_SPI
},
53 {"6 - LPSS1_F6_Reserved", BIT_LPSS1_F6_XXX
},
54 {"7 - LPSS1_F7_Reserved", BIT_LPSS1_F7_XXX
},
55 {"8 - SCC_EMMC", BIT_SCC_EMMC
},
56 {"9 - SCC_SDIO", BIT_SCC_SDIO
},
57 {"10 - SCC_SDCARD", BIT_SCC_SDCARD
},
58 {"11 - SCC_MIPI", BIT_SCC_MIPI
},
59 {"12 - HDA", BIT_HDA
},
60 {"13 - LPE", BIT_LPE
},
61 {"14 - OTG", BIT_OTG
},
62 {"15 - USH", BIT_USH
},
63 {"16 - GBE", BIT_GBE
},
64 {"17 - SATA", BIT_SATA
},
65 {"18 - USB_EHCI", BIT_USB_EHCI
},
66 {"19 - SEC", BIT_SEC
},
67 {"20 - PCIE_PORT0", BIT_PCIE_PORT0
},
68 {"21 - PCIE_PORT1", BIT_PCIE_PORT1
},
69 {"22 - PCIE_PORT2", BIT_PCIE_PORT2
},
70 {"23 - PCIE_PORT3", BIT_PCIE_PORT3
},
71 {"24 - LPSS2_F0_DMA", BIT_LPSS2_F0_DMA
},
72 {"25 - LPSS2_F1_I2C1", BIT_LPSS2_F1_I2C1
},
73 {"26 - LPSS2_F2_I2C2", BIT_LPSS2_F2_I2C2
},
74 {"27 - LPSS2_F3_I2C3", BIT_LPSS2_F3_I2C3
},
75 {"28 - LPSS2_F3_I2C4", BIT_LPSS2_F4_I2C4
},
76 {"29 - LPSS2_F5_I2C5", BIT_LPSS2_F5_I2C5
},
77 {"30 - LPSS2_F6_I2C6", BIT_LPSS2_F6_I2C6
},
78 {"31 - LPSS2_F7_I2C7", BIT_LPSS2_F7_I2C7
},
79 {"32 - SMB", BIT_SMB
},
80 {"33 - OTG_SS_PHY", BIT_OTG_SS_PHY
},
81 {"34 - USH_SS_PHY", BIT_USH_SS_PHY
},
82 {"35 - DFX", BIT_DFX
},
85 static inline u32
pmc_reg_read(struct pmc_dev
*pmc
, int reg_offset
)
87 return readl(pmc
->regmap
+ reg_offset
);
90 static inline void pmc_reg_write(struct pmc_dev
*pmc
, int reg_offset
, u32 val
)
92 writel(val
, pmc
->regmap
+ reg_offset
);
95 static void pmc_power_off(void)
100 pr_info("Preparing to enter system sleep state S5\n");
102 pm1_cnt_port
= acpi_base_addr
+ PM1_CNT
;
104 pm1_cnt_value
= inl(pm1_cnt_port
);
105 pm1_cnt_value
&= SLEEP_TYPE_MASK
;
106 pm1_cnt_value
|= SLEEP_TYPE_S5
;
107 pm1_cnt_value
|= SLEEP_ENABLE
;
109 outl(pm1_cnt_value
, pm1_cnt_port
);
112 static void pmc_hw_reg_setup(struct pmc_dev
*pmc
)
115 * Disable PMC S0IX_WAKE_EN events coming from:
117 * - GPIO_SUS ored dedicated IRQs
118 * - GPIO_SCORE ored dedicated IRQs
119 * - GPIO_SUS shared IRQ
120 * - GPIO_SCORE shared IRQ
122 pmc_reg_write(pmc
, PMC_S0IX_WAKE_EN
, (u32
)PMC_WAKE_EN_SETTING
);
125 #ifdef CONFIG_DEBUG_FS
126 static int pmc_dev_state_show(struct seq_file
*s
, void *unused
)
128 struct pmc_dev
*pmc
= s
->private;
129 u32 func_dis
, func_dis_2
, func_dis_index
;
130 u32 d3_sts_0
, d3_sts_1
, d3_sts_index
;
131 int dev_num
, dev_index
, reg_index
;
133 func_dis
= pmc_reg_read(pmc
, PMC_FUNC_DIS
);
134 func_dis_2
= pmc_reg_read(pmc
, PMC_FUNC_DIS_2
);
135 d3_sts_0
= pmc_reg_read(pmc
, PMC_D3_STS_0
);
136 d3_sts_1
= pmc_reg_read(pmc
, PMC_D3_STS_1
);
138 dev_num
= ARRAY_SIZE(dev_map
);
140 for (dev_index
= 0; dev_index
< dev_num
; dev_index
++) {
141 reg_index
= dev_index
/ PMC_REG_BIT_WIDTH
;
143 func_dis_index
= func_dis_2
;
144 d3_sts_index
= d3_sts_1
;
146 func_dis_index
= func_dis
;
147 d3_sts_index
= d3_sts_0
;
150 seq_printf(s
, "Dev: %-32s\tState: %s [%s]\n",
151 dev_map
[dev_index
].name
,
152 dev_map
[dev_index
].bit_mask
& func_dis_index
?
153 "Disabled" : "Enabled ",
154 dev_map
[dev_index
].bit_mask
& d3_sts_index
?
160 static int pmc_dev_state_open(struct inode
*inode
, struct file
*file
)
162 return single_open(file
, pmc_dev_state_show
, inode
->i_private
);
165 static const struct file_operations pmc_dev_state_ops
= {
166 .open
= pmc_dev_state_open
,
169 .release
= single_release
,
172 static int pmc_sleep_tmr_show(struct seq_file
*s
, void *unused
)
174 struct pmc_dev
*pmc
= s
->private;
175 u64 s0ir_tmr
, s0i1_tmr
, s0i2_tmr
, s0i3_tmr
, s0_tmr
;
177 s0ir_tmr
= (u64
)pmc_reg_read(pmc
, PMC_S0IR_TMR
) << PMC_TMR_SHIFT
;
178 s0i1_tmr
= (u64
)pmc_reg_read(pmc
, PMC_S0I1_TMR
) << PMC_TMR_SHIFT
;
179 s0i2_tmr
= (u64
)pmc_reg_read(pmc
, PMC_S0I2_TMR
) << PMC_TMR_SHIFT
;
180 s0i3_tmr
= (u64
)pmc_reg_read(pmc
, PMC_S0I3_TMR
) << PMC_TMR_SHIFT
;
181 s0_tmr
= (u64
)pmc_reg_read(pmc
, PMC_S0_TMR
) << PMC_TMR_SHIFT
;
183 seq_printf(s
, "S0IR Residency:\t%lldus\n", s0ir_tmr
);
184 seq_printf(s
, "S0I1 Residency:\t%lldus\n", s0i1_tmr
);
185 seq_printf(s
, "S0I2 Residency:\t%lldus\n", s0i2_tmr
);
186 seq_printf(s
, "S0I3 Residency:\t%lldus\n", s0i3_tmr
);
187 seq_printf(s
, "S0 Residency:\t%lldus\n", s0_tmr
);
191 static int pmc_sleep_tmr_open(struct inode
*inode
, struct file
*file
)
193 return single_open(file
, pmc_sleep_tmr_show
, inode
->i_private
);
196 static const struct file_operations pmc_sleep_tmr_ops
= {
197 .open
= pmc_sleep_tmr_open
,
200 .release
= single_release
,
203 static void pmc_dbgfs_unregister(struct pmc_dev
*pmc
)
208 debugfs_remove_recursive(pmc
->dbgfs_dir
);
209 pmc
->dbgfs_dir
= NULL
;
212 static int pmc_dbgfs_register(struct pmc_dev
*pmc
, struct pci_dev
*pdev
)
214 struct dentry
*dir
, *f
;
216 dir
= debugfs_create_dir("pmc_atom", NULL
);
220 f
= debugfs_create_file("dev_state", S_IFREG
| S_IRUGO
,
221 dir
, pmc
, &pmc_dev_state_ops
);
223 dev_err(&pdev
->dev
, "dev_states register failed\n");
226 f
= debugfs_create_file("sleep_state", S_IFREG
| S_IRUGO
,
227 dir
, pmc
, &pmc_sleep_tmr_ops
);
229 dev_err(&pdev
->dev
, "sleep_state register failed\n");
232 pmc
->dbgfs_dir
= dir
;
235 pmc_dbgfs_unregister(pmc
);
239 static int pmc_dbgfs_register(struct pmc_dev
*pmc
, struct pci_dev
*pdev
)
243 #endif /* CONFIG_DEBUG_FS */
245 static int pmc_setup_dev(struct pci_dev
*pdev
)
247 struct pmc_dev
*pmc
= &pmc_device
;
250 /* Obtain ACPI base address */
251 pci_read_config_dword(pdev
, ACPI_BASE_ADDR_OFFSET
, &acpi_base_addr
);
252 acpi_base_addr
&= ACPI_BASE_ADDR_MASK
;
254 /* Install power off function */
255 if (acpi_base_addr
!= 0 && pm_power_off
== NULL
)
256 pm_power_off
= pmc_power_off
;
258 pci_read_config_dword(pdev
, PMC_BASE_ADDR_OFFSET
, &pmc
->base_addr
);
259 pmc
->base_addr
&= PMC_BASE_ADDR_MASK
;
261 pmc
->regmap
= ioremap_nocache(pmc
->base_addr
, PMC_MMIO_REG_LEN
);
263 dev_err(&pdev
->dev
, "error: ioremap failed\n");
267 /* PMC hardware registers setup */
268 pmc_hw_reg_setup(pmc
);
270 ret
= pmc_dbgfs_register(pmc
, pdev
);
272 iounmap(pmc
->regmap
);
279 * Data for PCI driver interface
281 * This data only exists for exporting the supported
282 * PCI ids via MODULE_DEVICE_TABLE. We do not actually
283 * register a pci_driver, because lpc_ich will register
284 * a driver on the same PCI id.
286 static const struct pci_device_id pmc_pci_ids
[] = {
287 { PCI_DEVICE(PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_VLV_PMC
) },
291 MODULE_DEVICE_TABLE(pci
, pmc_pci_ids
);
293 static int __init
pmc_atom_init(void)
296 struct pci_dev
*pdev
= NULL
;
297 const struct pci_device_id
*ent
;
299 /* We look for our device - PCU PMC
300 * we assume that there is max. one device.
302 * We can't use plain pci_driver mechanism,
303 * as the device is really a multiple function device,
304 * main driver that binds to the pci_device is lpc_ich
305 * and have to find & bind to the device this way.
307 for_each_pci_dev(pdev
) {
308 ent
= pci_match_id(pmc_pci_ids
, pdev
);
310 err
= pmc_setup_dev(pdev
);
314 /* Device not found. */
319 module_init(pmc_atom_init
);
320 /* no module_exit, this driver shouldn't be unloaded */
322 MODULE_AUTHOR("Aubrey Li <aubrey.li@linux.intel.com>");
323 MODULE_DESCRIPTION("Intel Atom SOC Power Management Controller Interface");
324 MODULE_LICENSE("GPL v2");