20 #include <linux/errno.h>
22 #include <linux/device.h>
24 #include <linux/pci.h>
27 #include <linux/module.h>
32 #define IPCMSG_WATCHDOG_TIMER 0xF8
33 #define IPCMSG_BATTERY 0xEF
34 #define IPCMSG_FW_UPDATE 0xFE
35 #define IPCMSG_PCNTRL 0xFF
36 #define IPCMSG_FW_REVISION 0xF4
39 #define IPC_CMD_PCNTRL_W 0
40 #define IPC_CMD_PCNTRL_R 1
41 #define IPC_CMD_PCNTRL_M 2
61 #define IPC_BASE_ADDR 0xFF11C000
62 #define IPC_MAX_ADDR 0x100
63 #define IPC_WWBUF_SIZE 20
64 #define IPC_RWBUF_SIZE 20
65 #define IPC_I2C_BASE 0xFF12B000
66 #define IPC_I2C_MAX_ADDR 0x10
69 static void ipc_remove(
struct pci_dev *pdev);
86 #define IPC_READ_BUFFER 0x90
88 #define IPC_I2C_CNTRL_ADDR 0
89 #define I2C_DATA_ADDR 0x04
99 static inline void ipc_command(
u32 cmd)
101 writel(cmd, ipcdev.ipc_base);
111 writel(data, ipcdev.ipc_base + 0x80 + offset);
122 static inline u8 ipc_read_status(
void)
137 static inline int busy_loop(
void)
142 status = ipc_read_status();
145 status = ipc_read_status();
148 if (loop_count > 100000) {
149 dev_err(&ipcdev.pdev->dev,
"IPC timed out");
153 if ((status >> 1) & 1)
170 memset(cbuf, 0,
sizeof(cbuf));
172 if (ipcdev.pdev ==
NULL) {
177 for (nc = 0; nc <
count; nc++, offset += 2) {
179 cbuf[offset + 1] = addr[nc] >> 8;
183 for (nc = 0, offset = 0; nc <
count; nc++, offset += 4)
184 ipc_data_writel(wbuf[nc], offset);
185 ipc_command((count*2) << 16 |
id << 12 | 0 << 8 | op);
187 for (nc = 0; nc <
count; nc++, offset += 1)
188 cbuf[offset] = data[nc];
189 for (nc = 0, offset = 0; nc <
count; nc++, offset += 4)
190 ipc_data_writel(wbuf[nc], offset);
191 ipc_command((count*3) << 16 |
id << 12 | 0 << 8 | op);
194 cbuf[offset + 1] = data[1];
195 ipc_data_writel(wbuf[0], 0);
196 ipc_command(4 << 16 |
id << 12 | 0 << 8 | op);
203 for (nc = 0; nc <
count; nc++)
204 data[nc] = ipc_data_readb(nc);
255 u16 x[4] = {
addr, addr + 1, addr + 2, addr + 3};
305 u16 x[4] = {
addr, addr + 1, addr + 2, addr + 3};
367 u8 data[2] = {
bits, mask };
389 if (ipcdev.pdev ==
NULL) {
393 ipc_command(sub << 12 | cmd);
419 if (ipcdev.pdev ==
NULL) {
424 for (i = 0; i <
inlen; i++)
425 ipc_data_writel(*in++, 4 * i);
427 ipc_command((inlen << 16) | (sub << 12) | cmd);
430 for (i = 0; i <
outlen; i++)
431 *out++ = ipc_data_readl(4 * i);
439 #define IPC_I2C_WRITE 1
440 #define IPC_I2C_READ 2
459 if (ipcdev.pdev ==
NULL) {
463 cmd = (addr >> 24) & 0xFF;
475 "intel_scu_ipc: I2C INVALID_CMD = 0x%x\n", cmd);
531 if (!ipcdev.ipc_base)
535 if (!ipcdev.i2c_base) {
573 .name =
"intel_scu_ipc",
576 .remove = ipc_remove,
580 static int __init intel_scu_ipc_init(
void)
585 return pci_register_driver(&ipc_driver);
588 static void __exit intel_scu_ipc_exit(
void)