This source file includes following definitions.
- ipc_command
- ipc_data_writel
- ipc_read_status
- ipc_data_readb
- ipc_data_readl
- busy_loop
- ipc_wait_for_interrupt
- intel_scu_ipc_check_status
- pwr_reg_rdwr
- intel_scu_ipc_ioread8
- intel_scu_ipc_ioread16
- intel_scu_ipc_ioread32
- intel_scu_ipc_iowrite8
- intel_scu_ipc_iowrite16
- intel_scu_ipc_iowrite32
- intel_scu_ipc_readv
- intel_scu_ipc_writev
- intel_scu_ipc_update_register
- intel_scu_ipc_simple_command
- intel_scu_ipc_command
- intel_scu_ipc_raw_command
- intel_scu_ipc_i2c_cntrl
- ioc
- ipc_probe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include <linux/delay.h>
17 #include <linux/device.h>
18 #include <linux/errno.h>
19 #include <linux/init.h>
20 #include <linux/interrupt.h>
21 #include <linux/pci.h>
22 #include <linux/pm.h>
23 #include <linux/sfi.h>
24
25 #include <asm/intel-mid.h>
26 #include <asm/intel_scu_ipc.h>
27
28
29 #define IPCMSG_WATCHDOG_TIMER 0xF8
30 #define IPCMSG_BATTERY 0xEF
31 #define IPCMSG_FW_UPDATE 0xFE
32 #define IPCMSG_PCNTRL 0xFF
33 #define IPCMSG_FW_REVISION 0xF4
34
35
36 #define IPC_CMD_PCNTRL_W 0
37 #define IPC_CMD_PCNTRL_R 1
38 #define IPC_CMD_PCNTRL_M 2
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 #define IPC_WWBUF_SIZE 20
58 #define IPC_RWBUF_SIZE 20
59 #define IPC_IOC 0x100
60
61 #define PCI_DEVICE_ID_LINCROFT 0x082a
62 #define PCI_DEVICE_ID_PENWELL 0x080e
63 #define PCI_DEVICE_ID_CLOVERVIEW 0x08ea
64 #define PCI_DEVICE_ID_TANGIER 0x11a0
65
66
67 struct intel_scu_ipc_pdata_t {
68 u32 i2c_base;
69 u32 i2c_len;
70 };
71
72 static const struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = {
73 .i2c_base = 0xff12b000,
74 .i2c_len = 0x10,
75 };
76
77
78 static const struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = {
79 .i2c_base = 0xff12b000,
80 .i2c_len = 0x10,
81 };
82
83 static const struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = {
84 .i2c_base = 0xff00d000,
85 .i2c_len = 0x10,
86 };
87
88 struct intel_scu_ipc_dev {
89 struct device *dev;
90 void __iomem *ipc_base;
91 void __iomem *i2c_base;
92 struct completion cmd_complete;
93 u8 irq_mode;
94 };
95
96 static struct intel_scu_ipc_dev ipcdev;
97
98 #define IPC_STATUS 0x04
99 #define IPC_STATUS_IRQ BIT(2)
100
101
102
103
104
105
106 #define IPC_READ_BUFFER 0x90
107
108 #define IPC_I2C_CNTRL_ADDR 0
109 #define I2C_DATA_ADDR 0x04
110
111 static DEFINE_MUTEX(ipclock);
112
113
114
115
116
117
118
119
120 static inline void ipc_command(struct intel_scu_ipc_dev *scu, u32 cmd)
121 {
122 reinit_completion(&scu->cmd_complete);
123 writel(cmd | IPC_IOC, scu->ipc_base);
124 }
125
126
127
128
129
130
131
132 static inline void ipc_data_writel(struct intel_scu_ipc_dev *scu, u32 data, u32 offset)
133 {
134 writel(data, scu->ipc_base + 0x80 + offset);
135 }
136
137
138
139
140
141
142
143
144 static inline u8 ipc_read_status(struct intel_scu_ipc_dev *scu)
145 {
146 return __raw_readl(scu->ipc_base + 0x04);
147 }
148
149
150 static inline u8 ipc_data_readb(struct intel_scu_ipc_dev *scu, u32 offset)
151 {
152 return readb(scu->ipc_base + IPC_READ_BUFFER + offset);
153 }
154
155
156 static inline u32 ipc_data_readl(struct intel_scu_ipc_dev *scu, u32 offset)
157 {
158 return readl(scu->ipc_base + IPC_READ_BUFFER + offset);
159 }
160
161
162 static inline int busy_loop(struct intel_scu_ipc_dev *scu)
163 {
164 u32 status = ipc_read_status(scu);
165 u32 loop_count = 100000;
166
167
168 while ((status & BIT(0)) && --loop_count) {
169 udelay(1);
170 status = ipc_read_status(scu);
171 }
172
173 if (status & BIT(0)) {
174 dev_err(scu->dev, "IPC timed out");
175 return -ETIMEDOUT;
176 }
177
178 if (status & BIT(1))
179 return -EIO;
180
181 return 0;
182 }
183
184
185 static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu)
186 {
187 int status;
188
189 if (!wait_for_completion_timeout(&scu->cmd_complete, 3 * HZ)) {
190 dev_err(scu->dev, "IPC timed out\n");
191 return -ETIMEDOUT;
192 }
193
194 status = ipc_read_status(scu);
195 if (status & BIT(1))
196 return -EIO;
197
198 return 0;
199 }
200
201 static int intel_scu_ipc_check_status(struct intel_scu_ipc_dev *scu)
202 {
203 return scu->irq_mode ? ipc_wait_for_interrupt(scu) : busy_loop(scu);
204 }
205
206
207 static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
208 {
209 struct intel_scu_ipc_dev *scu = &ipcdev;
210 int nc;
211 u32 offset = 0;
212 int err;
213 u8 cbuf[IPC_WWBUF_SIZE];
214 u32 *wbuf = (u32 *)&cbuf;
215
216 memset(cbuf, 0, sizeof(cbuf));
217
218 mutex_lock(&ipclock);
219
220 if (scu->dev == NULL) {
221 mutex_unlock(&ipclock);
222 return -ENODEV;
223 }
224
225 for (nc = 0; nc < count; nc++, offset += 2) {
226 cbuf[offset] = addr[nc];
227 cbuf[offset + 1] = addr[nc] >> 8;
228 }
229
230 if (id == IPC_CMD_PCNTRL_R) {
231 for (nc = 0, offset = 0; nc < count; nc++, offset += 4)
232 ipc_data_writel(scu, wbuf[nc], offset);
233 ipc_command(scu, (count * 2) << 16 | id << 12 | 0 << 8 | op);
234 } else if (id == IPC_CMD_PCNTRL_W) {
235 for (nc = 0; nc < count; nc++, offset += 1)
236 cbuf[offset] = data[nc];
237 for (nc = 0, offset = 0; nc < count; nc++, offset += 4)
238 ipc_data_writel(scu, wbuf[nc], offset);
239 ipc_command(scu, (count * 3) << 16 | id << 12 | 0 << 8 | op);
240 } else if (id == IPC_CMD_PCNTRL_M) {
241 cbuf[offset] = data[0];
242 cbuf[offset + 1] = data[1];
243 ipc_data_writel(scu, wbuf[0], 0);
244 ipc_command(scu, 4 << 16 | id << 12 | 0 << 8 | op);
245 }
246
247 err = intel_scu_ipc_check_status(scu);
248 if (!err && id == IPC_CMD_PCNTRL_R) {
249
250 memcpy_fromio(cbuf, scu->ipc_base + 0x90, 16);
251 for (nc = 0; nc < count; nc++)
252 data[nc] = ipc_data_readb(scu, nc);
253 }
254 mutex_unlock(&ipclock);
255 return err;
256 }
257
258
259
260
261
262
263
264
265
266
267
268 int intel_scu_ipc_ioread8(u16 addr, u8 *data)
269 {
270 return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
271 }
272 EXPORT_SYMBOL(intel_scu_ipc_ioread8);
273
274
275
276
277
278
279
280
281
282
283
284 int intel_scu_ipc_ioread16(u16 addr, u16 *data)
285 {
286 u16 x[2] = {addr, addr + 1};
287 return pwr_reg_rdwr(x, (u8 *)data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
288 }
289 EXPORT_SYMBOL(intel_scu_ipc_ioread16);
290
291
292
293
294
295
296
297
298
299
300
301 int intel_scu_ipc_ioread32(u16 addr, u32 *data)
302 {
303 u16 x[4] = {addr, addr + 1, addr + 2, addr + 3};
304 return pwr_reg_rdwr(x, (u8 *)data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
305 }
306 EXPORT_SYMBOL(intel_scu_ipc_ioread32);
307
308
309
310
311
312
313
314
315
316
317
318 int intel_scu_ipc_iowrite8(u16 addr, u8 data)
319 {
320 return pwr_reg_rdwr(&addr, &data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
321 }
322 EXPORT_SYMBOL(intel_scu_ipc_iowrite8);
323
324
325
326
327
328
329
330
331
332
333
334 int intel_scu_ipc_iowrite16(u16 addr, u16 data)
335 {
336 u16 x[2] = {addr, addr + 1};
337 return pwr_reg_rdwr(x, (u8 *)&data, 2, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
338 }
339 EXPORT_SYMBOL(intel_scu_ipc_iowrite16);
340
341
342
343
344
345
346
347
348
349
350
351 int intel_scu_ipc_iowrite32(u16 addr, u32 data)
352 {
353 u16 x[4] = {addr, addr + 1, addr + 2, addr + 3};
354 return pwr_reg_rdwr(x, (u8 *)&data, 4, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
355 }
356 EXPORT_SYMBOL(intel_scu_ipc_iowrite32);
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371 int intel_scu_ipc_readv(u16 *addr, u8 *data, int len)
372 {
373 return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_R);
374 }
375 EXPORT_SYMBOL(intel_scu_ipc_readv);
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391 int intel_scu_ipc_writev(u16 *addr, u8 *data, int len)
392 {
393 return pwr_reg_rdwr(addr, data, len, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_W);
394 }
395 EXPORT_SYMBOL(intel_scu_ipc_writev);
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412 int intel_scu_ipc_update_register(u16 addr, u8 bits, u8 mask)
413 {
414 u8 data[2] = { bits, mask };
415 return pwr_reg_rdwr(&addr, data, 1, IPCMSG_PCNTRL, IPC_CMD_PCNTRL_M);
416 }
417 EXPORT_SYMBOL(intel_scu_ipc_update_register);
418
419
420
421
422
423
424
425
426
427
428
429
430
431 int intel_scu_ipc_simple_command(int cmd, int sub)
432 {
433 struct intel_scu_ipc_dev *scu = &ipcdev;
434 int err;
435
436 mutex_lock(&ipclock);
437 if (scu->dev == NULL) {
438 mutex_unlock(&ipclock);
439 return -ENODEV;
440 }
441 ipc_command(scu, sub << 12 | cmd);
442 err = intel_scu_ipc_check_status(scu);
443 mutex_unlock(&ipclock);
444 return err;
445 }
446 EXPORT_SYMBOL(intel_scu_ipc_simple_command);
447
448
449
450
451
452
453
454
455
456
457
458
459
460 int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
461 u32 *out, int outlen)
462 {
463 struct intel_scu_ipc_dev *scu = &ipcdev;
464 int i, err;
465
466 mutex_lock(&ipclock);
467 if (scu->dev == NULL) {
468 mutex_unlock(&ipclock);
469 return -ENODEV;
470 }
471
472 for (i = 0; i < inlen; i++)
473 ipc_data_writel(scu, *in++, 4 * i);
474
475 ipc_command(scu, (inlen << 16) | (sub << 12) | cmd);
476 err = intel_scu_ipc_check_status(scu);
477
478 if (!err) {
479 for (i = 0; i < outlen; i++)
480 *out++ = ipc_data_readl(scu, 4 * i);
481 }
482
483 mutex_unlock(&ipclock);
484 return err;
485 }
486 EXPORT_SYMBOL(intel_scu_ipc_command);
487
488 #define IPC_SPTR 0x08
489 #define IPC_DPTR 0x0C
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506 int intel_scu_ipc_raw_command(int cmd, int sub, u8 *in, int inlen,
507 u32 *out, int outlen, u32 dptr, u32 sptr)
508 {
509 struct intel_scu_ipc_dev *scu = &ipcdev;
510 int inbuflen = DIV_ROUND_UP(inlen, 4);
511 u32 inbuf[4];
512 int i, err;
513
514
515 if (inbuflen > 4)
516 return -EINVAL;
517
518 mutex_lock(&ipclock);
519 if (scu->dev == NULL) {
520 mutex_unlock(&ipclock);
521 return -ENODEV;
522 }
523
524 writel(dptr, scu->ipc_base + IPC_DPTR);
525 writel(sptr, scu->ipc_base + IPC_SPTR);
526
527
528
529
530
531
532
533
534 memcpy(inbuf, in, inlen);
535
536 for (i = 0; i < inbuflen; i++)
537 ipc_data_writel(scu, inbuf[i], 4 * i);
538
539 ipc_command(scu, (inlen << 16) | (sub << 12) | cmd);
540 err = intel_scu_ipc_check_status(scu);
541 if (!err) {
542 for (i = 0; i < outlen; i++)
543 *out++ = ipc_data_readl(scu, 4 * i);
544 }
545
546 mutex_unlock(&ipclock);
547 return err;
548 }
549 EXPORT_SYMBOL_GPL(intel_scu_ipc_raw_command);
550
551
552 #define IPC_I2C_WRITE 1
553 #define IPC_I2C_READ 2
554
555
556
557
558
559
560
561
562
563
564
565
566
567 int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data)
568 {
569 struct intel_scu_ipc_dev *scu = &ipcdev;
570 u32 cmd = 0;
571
572 mutex_lock(&ipclock);
573 if (scu->dev == NULL) {
574 mutex_unlock(&ipclock);
575 return -ENODEV;
576 }
577 cmd = (addr >> 24) & 0xFF;
578 if (cmd == IPC_I2C_READ) {
579 writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR);
580
581 usleep_range(1000, 2000);
582 *data = readl(scu->i2c_base + I2C_DATA_ADDR);
583 } else if (cmd == IPC_I2C_WRITE) {
584 writel(*data, scu->i2c_base + I2C_DATA_ADDR);
585 usleep_range(1000, 2000);
586 writel(addr, scu->i2c_base + IPC_I2C_CNTRL_ADDR);
587 } else {
588 dev_err(scu->dev,
589 "intel_scu_ipc: I2C INVALID_CMD = 0x%x\n", cmd);
590
591 mutex_unlock(&ipclock);
592 return -EIO;
593 }
594 mutex_unlock(&ipclock);
595 return 0;
596 }
597 EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl);
598
599
600
601
602
603
604
605
606 static irqreturn_t ioc(int irq, void *dev_id)
607 {
608 struct intel_scu_ipc_dev *scu = dev_id;
609 int status = ipc_read_status(scu);
610
611 writel(status | IPC_STATUS_IRQ, scu->ipc_base + IPC_STATUS);
612 complete(&scu->cmd_complete);
613
614 return IRQ_HANDLED;
615 }
616
617
618
619
620
621
622
623
624
625 static int ipc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
626 {
627 int err;
628 struct intel_scu_ipc_dev *scu = &ipcdev;
629 struct intel_scu_ipc_pdata_t *pdata;
630
631 if (scu->dev)
632 return -EBUSY;
633
634 pdata = (struct intel_scu_ipc_pdata_t *)id->driver_data;
635 if (!pdata)
636 return -ENODEV;
637
638 err = pcim_enable_device(pdev);
639 if (err)
640 return err;
641
642 err = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));
643 if (err)
644 return err;
645
646 init_completion(&scu->cmd_complete);
647
648 scu->ipc_base = pcim_iomap_table(pdev)[0];
649
650 scu->i2c_base = ioremap_nocache(pdata->i2c_base, pdata->i2c_len);
651 if (!scu->i2c_base)
652 return -ENOMEM;
653
654 err = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_scu_ipc",
655 scu);
656 if (err)
657 return err;
658
659
660 scu->dev = &pdev->dev;
661
662 intel_scu_devices_create();
663
664 pci_set_drvdata(pdev, scu);
665 return 0;
666 }
667
668 #define SCU_DEVICE(id, pdata) {PCI_VDEVICE(INTEL, id), (kernel_ulong_t)&pdata}
669
670 static const struct pci_device_id pci_ids[] = {
671 SCU_DEVICE(PCI_DEVICE_ID_LINCROFT, intel_scu_ipc_lincroft_pdata),
672 SCU_DEVICE(PCI_DEVICE_ID_PENWELL, intel_scu_ipc_penwell_pdata),
673 SCU_DEVICE(PCI_DEVICE_ID_CLOVERVIEW, intel_scu_ipc_penwell_pdata),
674 SCU_DEVICE(PCI_DEVICE_ID_TANGIER, intel_scu_ipc_tangier_pdata),
675 {}
676 };
677
678 static struct pci_driver ipc_driver = {
679 .driver = {
680 .suppress_bind_attrs = true,
681 },
682 .name = "intel_scu_ipc",
683 .id_table = pci_ids,
684 .probe = ipc_probe,
685 };
686 builtin_pci_driver(ipc_driver);