aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86
diff options
context:
space:
mode:
authorSreedhara DS <sreedhara.ds@intel.com>2010-04-26 13:13:05 -0400
committerMatthew Garrett <mjg@redhat.com>2010-05-17 12:06:07 -0400
commit9a58a3333923c7fef4ba6ac9afd817429e63a1fe (patch)
treed03aa10c45b458a1661b6f35e1763c9cdbb8104e /drivers/platform/x86
parentd5c051f1080e0eec55f3fc42c37d941681941628 (diff)
IPC driver for Intel Mobile Internet Device (MID) platforms
The IPC (inter processor communications) is used to provide the communications between kernel and system control units on some embedded Intel x86 platforms. (Various bits of clean up and restructuring by Alan Cox) Signed-off-by: Sreedhara DS <sreedhara.ds@intel.com> Signed-off-by: Alan Cox <alan@linux.intel.com>
Diffstat (limited to 'drivers/platform/x86')
-rw-r--r--drivers/platform/x86/Kconfig8
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/intel_scu_ipc.c829
3 files changed, 838 insertions, 0 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 6c3320d75055..619134151ca6 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -527,4 +527,12 @@ config ACPI_CMPC
527 keys as input device, backlight device, tablet and accelerometer 527 keys as input device, backlight device, tablet and accelerometer
528 devices. 528 devices.
529 529
530config INTEL_SCU_IPC
531 bool "Intel SCU IPC Support"
532 depends on X86_MRST
533 default y
534 ---help---
535 IPC is used to bridge the communications between kernel and SCU on
536 some embedded Intel x86 platforms.
537
530endif # X86_PLATFORM_DEVICES 538endif # X86_PLATFORM_DEVICES
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index a906490e3530..8770bfe71431 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -25,3 +25,4 @@ obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o
25obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o 25obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o
26obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o 26obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
27obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o 27obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o
28obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
new file mode 100644
index 000000000000..576c3ed92435
--- /dev/null
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -0,0 +1,829 @@
1/*
2 * intel_scu_ipc.c: Driver for the Intel SCU IPC mechanism
3 *
4 * (C) Copyright 2008-2010 Intel Corporation
5 * Author: Sreedhara DS (sreedhara.ds@intel.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2
10 * of the License.
11 *
12 * SCU runing in ARC processor communicates with other entity running in IA
13 * core through IPC mechanism which in turn messaging between IA core ad SCU.
14 * SCU has two IPC mechanism IPC-1 and IPC-2. IPC-1 is used between IA32 and
15 * SCU where IPC-2 is used between P-Unit and SCU. This driver delas with
16 * IPC-1 Driver provides an API for power control unit registers (e.g. MSIC)
17 * along with other APIs.
18 */
19#include <linux/delay.h>
20#include <linux/errno.h>
21#include <linux/init.h>
22#include <linux/sysdev.h>
23#include <linux/pm.h>
24#include <linux/pci.h>
25#include <linux/interrupt.h>
26#include <asm/setup.h>
27#include <asm/intel_scu_ipc.h>
28
29/* IPC defines the following message types */
30#define IPCMSG_WATCHDOG_TIMER 0xF8 /* Set Kernel Watchdog Threshold */
31#define IPCMSG_BATTERY 0xEF /* Coulomb Counter Accumulator */
32#define IPCMSG_FW_UPDATE 0xFE /* Firmware update */
33#define IPCMSG_PCNTRL 0xFF /* Power controller unit read/write */
34#define IPCMSG_FW_REVISION 0xF4 /* Get firmware revision */
35
36/* Command id associated with message IPCMSG_PCNTRL */
37#define IPC_CMD_PCNTRL_W 0 /* Register write */
38#define IPC_CMD_PCNTRL_R 1 /* Register read */
39#define IPC_CMD_PCNTRL_M 2 /* Register read-modify-write */
40
41/* Miscelaneous Command ids */
42#define IPC_CMD_INDIRECT_RD 2 /* 32bit indirect read */
43#define IPC_CMD_INDIRECT_WR 5 /* 32bit indirect write */
44
45/*
46 * IPC register summary
47 *
48 * IPC register blocks are memory mapped at fixed address of 0xFF11C000
49 * To read or write information to the SCU, driver writes to IPC-1 memory
50 * mapped registers (base address 0xFF11C000). The following is the IPC
51 * mechanism
52 *
53 * 1. IA core cDMI interface claims this transaction and converts it to a
54 * Transaction Layer Packet (TLP) message which is sent across the cDMI.
55 *
56 * 2. South Complex cDMI block receives this message and writes it to
57 * the IPC-1 register block, causing an interrupt to the SCU
58 *
59 * 3. SCU firmware decodes this interrupt and IPC message and the appropriate
60 * message handler is called within firmware.
61 */
62
63#define IPC_BASE_ADDR 0xFF11C000 /* IPC1 base register address */
64#define IPC_MAX_ADDR 0x100 /* Maximum IPC regisers */
65#define IPC_WWBUF_SIZE 16 /* IPC Write buffer Size */
66#define IPC_RWBUF_SIZE 16 /* IPC Read buffer Size */
67#define IPC_I2C_BASE 0xFF12B000 /* I2C control register base address */
68#define IPC_I2C_MAX_ADDR 0x10 /* Maximum I2C regisers */
69
70static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id);
71static void ipc_remove(struct pci_dev *pdev);
72
73struct intel_scu_ipc_dev {
74 struct pci_dev *pdev;
75 void __iomem *ipc_base;
76 void __iomem *i2c_base;
77};
78
79static struct intel_scu_ipc_dev ipcdev; /* Only one for now */
80
81static int platform = 1;
82module_param(platform, int, 0);
83MODULE_PARM_DESC(platform, "1 for moorestown platform");
84
85
86
87
88/*
89 * IPC Read Buffer (Read Only):
90 * 16 byte buffer for receiving data from SCU, if IPC command
91 * processing results in response data
92 */
93#define IPC_READ_BUFFER 0x90
94
95#define IPC_I2C_CNTRL_ADDR 0
96#define I2C_DATA_ADDR 0x04
97
98static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */
99
100/*
101 * Command Register (Write Only):
102 * A write to this register results in an interrupt to the SCU core processor
103 * Format:
104 * |rfu2(8) | size(8) | command id(4) | rfu1(3) | ioc(1) | command(8)|
105 */
106static inline void ipc_command(u32 cmd) /* Send ipc command */
107{
108 writel(cmd, ipcdev.ipc_base);
109}
110
111/*
112 * IPC Write Buffer (Write Only):
113 * 16-byte buffer for sending data associated with IPC command to
114 * SCU. Size of the data is specified in the IPC_COMMAND_REG register
115 */
116static inline void ipc_data_writel(u32 data, u32 offset) /* Write ipc data */
117{
118 writel(data, ipcdev.ipc_base + 0x80 + offset);
119}
120
121/*
122 * IPC destination Pointer (Write Only):
123 * Use content as pointer for destination write
124 */
125static inline void ipc_write_dptr(u32 data) /* Write dptr data */
126{
127 writel(data, ipcdev.ipc_base + 0x0C);
128}
129
130/*
131 * IPC Source Pointer (Write Only):
132 * Use content as pointer for read location
133*/
134static inline void ipc_write_sptr(u32 data) /* Write dptr data */
135{
136 writel(data, ipcdev.ipc_base + 0x08);
137}
138
139/*
140 * Status Register (Read Only):
141 * Driver will read this register to get the ready/busy status of the IPC
142 * block and error status of the IPC command that was just processed by SCU
143 * Format:
144 * |rfu3(8)|error code(8)|initiator id(8)|cmd id(4)|rfu1(2)|error(1)|busy(1)|
145 */
146
147static inline u8 ipc_read_status(void)
148{
149 return __raw_readl(ipcdev.ipc_base + 0x04);
150}
151
152static inline u8 ipc_data_readb(u32 offset) /* Read ipc byte data */
153{
154 return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
155}
156
157static inline u8 ipc_data_readl(u32 offset) /* Read ipc u32 data */
158{
159 return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
160}
161
162static inline int busy_loop(void) /* Wait till scu status is busy */
163{
164 u32 status = 0;
165 u32 loop_count = 0;
166
167 status = ipc_read_status();
168 while (status & 1) {
169 udelay(1); /* scu processing time is in few u secods */
170 status = ipc_read_status();
171 loop_count++;
172 /* break if scu doesn't reset busy bit after huge retry */
173 if (loop_count > 100000) {
174 dev_err(&ipcdev.pdev->dev, "IPC timed out");
175 return -ETIMEDOUT;
176 }
177 }
178 return (status >> 1) & 1;
179}
180
181/* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */
182static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
183{
184 int nc;
185 u32 offset = 0;
186 u32 err = 0;
187 u8 cbuf[IPC_WWBUF_SIZE] = { '\0' };
188 u32 *wbuf = (u32 *)&cbuf;
189
190 mutex_lock(&ipclock);
191 if (ipcdev.pdev == NULL) {
192 mutex_unlock(&ipclock);
193 return -ENODEV;
194 }
195
196 if (platform == 1) {
197 /* Entry is 4 bytes for read/write, 5 bytes for read modify */
198 for (nc = 0; nc < count; nc++) {
199 cbuf[offset] = addr[nc];
200 cbuf[offset + 1] = addr[nc] >> 8;
201 if (id != IPC_CMD_PCNTRL_R)
202 cbuf[offset + 2] = data[nc];
203 if (id == IPC_CMD_PCNTRL_M) {
204 cbuf[offset + 3] = data[nc + 1];
205 offset += 1;
206 }
207 offset += 3;
208 }
209 for (nc = 0, offset = 0; nc < count; nc++, offset += 4)
210 ipc_data_writel(wbuf[nc], offset); /* Write wbuff */
211
212 } else {
213 for (nc = 0, offset = 0; nc < count; nc++, offset += 2)
214 ipc_data_writel(addr[nc], offset); /* Write addresses */
215 if (id != IPC_CMD_PCNTRL_R) {
216 for (nc = 0; nc < count; nc++, offset++)
217 ipc_data_writel(data[nc], offset); /* Write data */
218 if (id == IPC_CMD_PCNTRL_M)
219 ipc_data_writel(data[nc + 1], offset); /* Mask value*/
220 }
221 }
222
223 if (id != IPC_CMD_PCNTRL_M)
224 ipc_command((count * 3) << 16 | id << 12 | 0 << 8 | op);
225 else
226 ipc_command((count * 4) << 16 | id << 12 | 0 << 8 | op);
227
228 err = busy_loop();
229
230 if (id == IPC_CMD_PCNTRL_R) { /* Read rbuf */
231 /* Workaround: values are read as 0 without memcpy_fromio */
232 memcpy_fromio(cbuf, ipcdev.ipc_base + IPC_READ_BUFFER, 16);
233 if (platform == 1) {
234 for (nc = 0, offset = 2; nc < count; nc++, offset += 3)
235 data[nc] = ipc_data_readb(offset);
236 } else {
237 for (nc = 0; nc < count; nc++)
238 data[nc] = ipc_data_readb(nc);
239 }
240 }
241 mutex_unlock(&ipclock);
242 return err;
243}
244
245/**
246 * intel_scu_ipc_ioread8 - read a word via the SCU
247 * @addr: register on SCU
248 * @data: return pointer for read byte
249 *
250 * Read a single register. Returns 0 on success or an error code. All
251 * locking between SCU accesses is handled for the caller.
252 *
253 * This function may sleep.
254 */
255int intel_scu_ipc_ioread8(u16 addr, u8 *data)
256{
257 return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
258}
259EXPORT_SYMBOL(intel_scu_ipc_ioread8);
260
261/**
262 * intel_scu_ipc_ioread16 - read a word via the SCU
263 * @addr: register on SCU
264 * @data: return pointer for read word
265 *
266 * Read a register pair. Returns 0 on success or an error code. All
267 * locking between SCU accesses is handled for the caller.
268 *
269 * This function may sleep.
270 */
271int intel_scu_ipc_ioread16(u16 addr, u16 *data)
272{
273 u16 x[2] = {addr, addr + 1 };
274 return pwr_reg_rdwr(x, (u8 *)data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
275}
276EXPORT_SYMBOL(intel_scu_ipc_ioread16);
277
278/**
279 * intel_scu_ipc_ioread32 - read a dword via the SCU
280 * @addr: register on SCU
281 * @data: return pointer for read dword
282 *
283 * Read four registers. Returns 0 on success or an error code. All
284 * locking between SCU accesses is handled for the caller.
285 *
286 * This function may sleep.
287 */
288int intel_scu_ipc_ioread32(u16 addr, u32 *data)
289{
290 u16 x[4] = {addr, addr + 1, addr + 2, addr + 3};
291 return pwr_reg_rdwr(x, (u8 *)data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
292}
293EXPORT_SYMBOL(intel_scu_ipc_ioread32);
294
295/**
296 * intel_scu_ipc_iowrite8 - write a byte via the SCU
297 * @addr: register on SCU
298 * @data: byte to write
299 *
300 * Write a single register. Returns 0 on success or an error code. All
301 * locking between SCU accesses is handled for the caller.
302 *
303 * This function may sleep.
304 */
305int intel_scu_ipc_iowrite8(u16 addr, u8 data)
306{
307 return pwr_reg_rdwr(&addr, &data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
308}
309EXPORT_SYMBOL(intel_scu_ipc_iowrite8);
310
311/**
312 * intel_scu_ipc_iowrite16 - write a word via the SCU
313 * @addr: register on SCU
314 * @data: word to write
315 *
316 * Write two registers. Returns 0 on success or an error code. All
317 * locking between SCU accesses is handled for the caller.
318 *
319 * This function may sleep.
320 */
321int intel_scu_ipc_iowrite16(u16 addr, u16 data)
322{
323 u16 x[2] = {addr, addr + 1 };
324 return pwr_reg_rdwr(x, (u8 *)&data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
325}
326EXPORT_SYMBOL(intel_scu_ipc_iowrite16);
327
328/**
329 * intel_scu_ipc_iowrite32 - write a dword via the SCU
330 * @addr: register on SCU
331 * @data: dword to write
332 *
333 * Write four registers. Returns 0 on success or an error code. All
334 * locking between SCU accesses is handled for the caller.
335 *
336 * This function may sleep.
337 */
338int intel_scu_ipc_iowrite32(u16 addr, u32 data)
339{
340 u16 x[4] = {addr, addr + 1, addr + 2, addr + 3};
341 return pwr_reg_rdwr(x, (u8 *)&data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
342}
343EXPORT_SYMBOL(intel_scu_ipc_iowrite32);
344
345/**
346 * intel_scu_ipc_readvv - read a set of registers
347 * @addr: register list
348 * @data: bytes to return
349 * @len: length of array
350 *
351 * Read registers. Returns 0 on success or an error code. All
352 * locking between SCU accesses is handled for the caller.
353 *
354 * The largest array length permitted by the hardware is 5 items.
355 *
356 * This function may sleep.
357 */
358int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
359{
360 return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
361}
362EXPORT_SYMBOL(intel_scu_ipc_readv);
363
364/**
365 * intel_scu_ipc_writev - write a set of registers
366 * @addr: register list
367 * @data: bytes to write
368 * @len: length of array
369 *
370 * Write registers. Returns 0 on success or an error code. All
371 * locking between SCU accesses is handled for the caller.
372 *
373 * The largest array length permitted by the hardware is 5 items.
374 *
375 * This function may sleep.
376 *
377 */
378int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
379{
380 return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
381}
382EXPORT_SYMBOL(intel_scu_ipc_writev);
383
384
385/**
386 * intel_scu_ipc_update_register - r/m/w a register
387 * @addr: register address
388 * @bits: bits to update
389 * @mask: mask of bits to update
390 *
391 * Read-modify-write power control unit register. The first data argument
392 * must be register value and second is mask value
393 * mask is a bitmap that indicates which bits to update.
394 * 0 = masked. Don't modify this bit, 1 = modify this bit.
395 * returns 0 on success or an error code.
396 *
397 * This function may sleep. Locking between SCU accesses is handled
398 * for the caller.
399 */
400int intel_scu_ipc_update_register(u16 addr, u8 bits, u8 mask)
401{
402 u8 data[2] = { bits, mask };
403 return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_M);
404}
405EXPORT_SYMBOL(intel_scu_ipc_update_register);
406
407/**
408 * intel_scu_ipc_register_read - 32bit indirect read
409 * @addr: register address
410 * @value: 32bit value return
411 *
412 * Performs IA 32 bit indirect read, returns 0 on success, or an
413 * error code.
414 *
415 * Can be used when SCCB(System Controller Configuration Block) register
416 * HRIM(Honor Restricted IPC Messages) is set (bit 23)
417 *
418 * This function may sleep. Locking for SCU accesses is handled for
419 * the caller.
420 */
421int intel_scu_ipc_register_read(u32 addr, u32 *value)
422{
423 u32 err = 0;
424
425 mutex_lock(&ipclock);
426 if (ipcdev.pdev == NULL) {
427 mutex_unlock(&ipclock);
428 return -ENODEV;
429 }
430 ipc_write_sptr(addr);
431 ipc_command(4 << 16 | IPC_CMD_INDIRECT_RD);
432 err = busy_loop();
433 *value = ipc_data_readl(0);
434 mutex_unlock(&ipclock);
435 return err;
436}
437EXPORT_SYMBOL(intel_scu_ipc_register_read);
438
439/**
440 * intel_scu_ipc_register_write - 32bit indirect write
441 * @addr: register address
442 * @value: 32bit value to write
443 *
444 * Performs IA 32 bit indirect write, returns 0 on success, or an
445 * error code.
446 *
447 * Can be used when SCCB(System Controller Configuration Block) register
448 * HRIM(Honor Restricted IPC Messages) is set (bit 23)
449 *
450 * This function may sleep. Locking for SCU accesses is handled for
451 * the caller.
452 */
453int intel_scu_ipc_register_write(u32 addr, u32 value)
454{
455 u32 err = 0;
456
457 mutex_lock(&ipclock);
458 if (ipcdev.pdev == NULL) {
459 mutex_unlock(&ipclock);
460 return -ENODEV;
461 }
462 ipc_write_dptr(addr);
463 ipc_data_writel(value, 0);
464 ipc_command(4 << 16 | IPC_CMD_INDIRECT_WR);
465 err = busy_loop();
466 mutex_unlock(&ipclock);
467 return err;
468}
469EXPORT_SYMBOL(intel_scu_ipc_register_write);
470
471/**
472 * intel_scu_ipc_simple_command - send a simple command
473 * @cmd: command
474 * @sub: sub type
475 *
476 * Issue a simple command to the SCU. Do not use this interface if
477 * you must then access data as any data values may be overwritten
478 * by another SCU access by the time this function returns.
479 *
480 * This function may sleep. Locking for SCU accesses is handled for
481 * the caller.
482 */
483int intel_scu_ipc_simple_command(int cmd, int sub)
484{
485 u32 err = 0;
486
487 mutex_lock(&ipclock);
488 if (ipcdev.pdev == NULL) {
489 mutex_unlock(&ipclock);
490 return -ENODEV;
491 }
492 ipc_command(cmd << 12 | sub);
493 err = busy_loop();
494 mutex_unlock(&ipclock);
495 return err;
496}
497EXPORT_SYMBOL(intel_scu_ipc_simple_command);
498
499/**
500 * intel_scu_ipc_command - command with data
501 * @cmd: command
502 * @sub: sub type
503 * @in: input data
504 * @inlen: input length
505 * @out: output data
506 * @outlein: output length
507 *
508 * Issue a command to the SCU which involves data transfers. Do the
509 * data copies under the lock but leave it for the caller to interpret
510 */
511
512int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
513 u32 *out, int outlen)
514{
515 u32 err = 0;
516 int i = 0;
517
518 mutex_lock(&ipclock);
519 if (ipcdev.pdev == NULL) {
520 mutex_unlock(&ipclock);
521 return -ENODEV;
522 }
523
524 for (i = 0; i < inlen; i++)
525 ipc_data_writel(*in++, 4 * i);
526
527 ipc_command(cmd << 12 | sub);
528 err = busy_loop();
529
530 for (i = 0; i < outlen; i++)
531 *out++ = ipc_data_readl(4 * i);
532
533 mutex_unlock(&ipclock);
534 return err;
535}
536EXPORT_SYMBOL(intel_scu_ipc_command);
537
538/*I2C commands */
539#define IPC_I2C_WRITE 1 /* I2C Write command */
540#define IPC_I2C_READ 2 /* I2C Read command */
541
542/**
543 * intel_scu_ipc_i2c_cntrl - I2C read/write operations
544 * @addr: I2C address + command bits
545 * @data: data to read/write
546 *
547 * Perform an an I2C read/write operation via the SCU. All locking is
548 * handled for the caller. This function may sleep.
549 *
550 * Returns an error code or 0 on success.
551 *
552 * This has to be in the IPC driver for the locking.
553 */
554int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data)
555{
556 u32 cmd = 0;
557
558 mutex_lock(&ipclock);
559 cmd = (addr >> 24) & 0xFF;
560 if (cmd == IPC_I2C_READ) {
561 writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR);
562 /* Write not getting updated without delay */
563 mdelay(1);
564 *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR);
565 } else if (cmd == IPC_I2C_WRITE) {
566 writel(addr, ipcdev.i2c_base + I2C_DATA_ADDR);
567 mdelay(1);
568 writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR);
569 } else {
570 dev_err(&ipcdev.pdev->dev,
571 "intel_scu_ipc: I2C INVALID_CMD = 0x%x\n", cmd);
572
573 mutex_unlock(&ipclock);
574 return -1;
575 }
576 mutex_unlock(&ipclock);
577 return 0;
578}
579EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl);
580
581#define IPC_FW_LOAD_ADDR 0xFFFC0000 /* Storage location for FW image */
582#define IPC_FW_UPDATE_MBOX_ADDR 0xFFFFDFF4 /* Mailbox between ipc and scu */
583#define IPC_MAX_FW_SIZE 262144 /* 256K storage size for loading the FW image */
584#define IPC_FW_MIP_HEADER_SIZE 2048 /* Firmware MIP header size */
585/* IPC inform SCU to get ready for update process */
586#define IPC_CMD_FW_UPDATE_READY 0x10FE
587/* IPC inform SCU to go for update process */
588#define IPC_CMD_FW_UPDATE_GO 0x20FE
589/* Status code for fw update */
590#define IPC_FW_UPDATE_SUCCESS 0x444f4e45 /* Status code 'DONE' */
591#define IPC_FW_UPDATE_BADN 0x4241444E /* Status code 'BADN' */
592#define IPC_FW_TXHIGH 0x54784849 /* Status code 'IPC_FW_TXHIGH' */
593#define IPC_FW_TXLOW 0x54784c4f /* Status code 'IPC_FW_TXLOW' */
594
595struct fw_update_mailbox {
596 u32 status;
597 u32 scu_flag;
598 u32 driver_flag;
599};
600
601
602/**
603 * intel_scu_ipc_fw_update - Firmware update utility
604 * @buffer: firmware buffer
605 * @length: size of firmware buffer
606 *
607 * This function provides an interface to load the firmware into
608 * the SCU. Returns 0 on success or -1 on failure
609 */
610int intel_scu_ipc_fw_update(u8 *buffer, u32 length)
611{
612 void __iomem *fw_update_base;
613 struct fw_update_mailbox __iomem *mailbox = NULL;
614 int retry_cnt = 0;
615 u32 status;
616
617 mutex_lock(&ipclock);
618 fw_update_base = ioremap_nocache(IPC_FW_LOAD_ADDR, (128*1024));
619 if (fw_update_base == NULL) {
620 mutex_unlock(&ipclock);
621 return -ENOMEM;
622 }
623 mailbox = ioremap_nocache(IPC_FW_UPDATE_MBOX_ADDR,
624 sizeof(struct fw_update_mailbox));
625 if (mailbox == NULL) {
626 iounmap(fw_update_base);
627 mutex_unlock(&ipclock);
628 return -ENOMEM;
629 }
630
631 ipc_command(IPC_CMD_FW_UPDATE_READY);
632
633 /* Intitialize mailbox */
634 writel(0, &mailbox->status);
635 writel(0, &mailbox->scu_flag);
636 writel(0, &mailbox->driver_flag);
637
638 /* Driver copies the 2KB MIP header to SRAM at 0xFFFC0000*/
639 memcpy_toio(fw_update_base, buffer, 0x800);
640
641 /* Driver sends "FW Update" IPC command (CMD_ID 0xFE; MSG_ID 0x02).
642 * Upon receiving this command, SCU will write the 2K MIP header
643 * from 0xFFFC0000 into NAND.
644 * SCU will write a status code into the Mailbox, and then set scu_flag.
645 */
646
647 ipc_command(IPC_CMD_FW_UPDATE_GO);
648
649 /*Driver stalls until scu_flag is set */
650 while (readl(&mailbox->scu_flag) != 1) {
651 rmb();
652 mdelay(1);
653 }
654
655 /* Driver checks Mailbox status.
656 * If the status is 'BADN', then abort (bad NAND).
657 * If the status is 'IPC_FW_TXLOW', then continue.
658 */
659 while (readl(&mailbox->status) != IPC_FW_TXLOW) {
660 rmb();
661 mdelay(10);
662 }
663 mdelay(10);
664
665update_retry:
666 if (retry_cnt > 5)
667 goto update_end;
668
669 if (readl(&mailbox->status) != IPC_FW_TXLOW)
670 goto update_end;
671 buffer = buffer + 0x800;
672 memcpy_toio(fw_update_base, buffer, 0x20000);
673 writel(1, &mailbox->driver_flag);
674 while (readl(&mailbox->scu_flag) == 1) {
675 rmb();
676 mdelay(1);
677 }
678
679 /* check for 'BADN' */
680 if (readl(&mailbox->status) == IPC_FW_UPDATE_BADN)
681 goto update_end;
682
683 while (readl(&mailbox->status) != IPC_FW_TXHIGH) {
684 rmb();
685 mdelay(10);
686 }
687 mdelay(10);
688
689 if (readl(&mailbox->status) != IPC_FW_TXHIGH)
690 goto update_end;
691
692 buffer = buffer + 0x20000;
693 memcpy_toio(fw_update_base, buffer, 0x20000);
694 writel(0, &mailbox->driver_flag);
695
696 while (mailbox->scu_flag == 0) {
697 rmb();
698 mdelay(1);
699 }
700
701 /* check for 'BADN' */
702 if (readl(&mailbox->status) == IPC_FW_UPDATE_BADN)
703 goto update_end;
704
705 if (readl(&mailbox->status) == IPC_FW_TXLOW) {
706 ++retry_cnt;
707 goto update_retry;
708 }
709
710update_end:
711 status = readl(&mailbox->status);
712
713 iounmap(fw_update_base);
714 iounmap(mailbox);
715 mutex_unlock(&ipclock);
716
717 if (status == IPC_FW_UPDATE_SUCCESS)
718 return 0;
719 return -1;
720}
721EXPORT_SYMBOL(intel_scu_ipc_fw_update);
722
723/*
724 * Interrupt handler gets called when ioc bit of IPC_COMMAND_REG set to 1
725 * When ioc bit is set to 1, caller api must wait for interrupt handler called
726 * which in turn unlocks the caller api. Currently this is not used
727 *
728 * This is edge triggered so we need take no action to clear anything
729 */
730static irqreturn_t ioc(int irq, void *dev_id)
731{
732 return IRQ_HANDLED;
733}
734
735/**
736 * ipc_probe - probe an Intel SCU IPC
737 * @dev: the PCI device matching
738 * @id: entry in the match table
739 *
740 * Enable and install an intel SCU IPC. This appears in the PCI space
741 * but uses some hard coded addresses as well.
742 */
743static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id)
744{
745 int err;
746 resource_size_t pci_resource;
747
748 if (ipcdev.pdev) /* We support only one SCU */
749 return -EBUSY;
750
751 ipcdev.pdev = pci_dev_get(dev);
752
753 err = pci_enable_device(dev);
754 if (err)
755 return err;
756
757 err = pci_request_regions(dev, "intel_scu_ipc");
758 if (err)
759 return err;
760
761 pci_resource = pci_resource_start(dev, 0);
762 if (!pci_resource)
763 return -ENOMEM;
764
765 if (request_irq(dev->irq, ioc, 0, "intel_scu_ipc", &ipcdev))
766 return -EBUSY;
767
768 ipcdev.ipc_base = ioremap_nocache(IPC_BASE_ADDR, IPC_MAX_ADDR);
769 if (!ipcdev.ipc_base)
770 return -ENOMEM;
771
772 ipcdev.i2c_base = ioremap_nocache(IPC_I2C_BASE, IPC_I2C_MAX_ADDR);
773 if (!ipcdev.i2c_base) {
774 iounmap(ipcdev.ipc_base);
775 return -ENOMEM;
776 }
777 return 0;
778}
779
780/**
781 * ipc_remove - remove a bound IPC device
782 * @pdev: PCI device
783 *
784 * In practice the SCU is not removable but this function is also
785 * called for each device on a module unload or cleanup which is the
786 * path that will get used.
787 *
788 * Free up the mappings and release the PCI resources
789 */
790static void ipc_remove(struct pci_dev *pdev)
791{
792 free_irq(pdev->irq, &ipcdev);
793 pci_release_regions(pdev);
794 pci_dev_put(ipcdev.pdev);
795 iounmap(ipcdev.ipc_base);
796 iounmap(ipcdev.i2c_base);
797 ipcdev.pdev = NULL;
798}
799
800static const struct pci_device_id pci_ids[] = {
801 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080e)},
802 { 0,}
803};
804MODULE_DEVICE_TABLE(pci, pci_ids);
805
806static struct pci_driver ipc_driver = {
807 .name = "intel_scu_ipc",
808 .id_table = pci_ids,
809 .probe = ipc_probe,
810 .remove = ipc_remove,
811};
812
813
814static int __init intel_scu_ipc_init(void)
815{
816 return pci_register_driver(&ipc_driver);
817}
818
819static void __exit intel_scu_ipc_exit(void)
820{
821 pci_unregister_driver(&ipc_driver);
822}
823
824MODULE_AUTHOR("Sreedhara DS <sreedhara.ds@intel.com>");
825MODULE_DESCRIPTION("Intel SCU IPC driver");
826MODULE_LICENSE("GPL");
827
828module_init(intel_scu_ipc_init);
829module_exit(intel_scu_ipc_exit);