1 // SPDX-License-Identifier: GPL-2.0-only
4 * Device Driver for the Infineon Technologies
5 * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module
6 * Specifications at www.trustedcomputinggroup.org
8 * Copyright (C) 2005, Marcel Selhorst <tpmdd@selhorst.net>
9 * Sirrix AG - security technologies <tpmdd@sirrix.com> and
10 * Applied Data Security Group, Ruhr-University Bochum, Germany
11 * Project-Homepage: http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/
14 #include <linux/init.h>
15 #include <linux/pnp.h>
18 /* Infineon specific definitions */
19 /* maximum number of WTX-packages */
20 #define TPM_MAX_WTX_PACKAGES 50
21 /* msleep-Time for WTX-packages */
22 #define TPM_WTX_MSLEEP_TIME 20
23 /* msleep-Time --> Interval to check status register */
24 #define TPM_MSLEEP_TIME 3
25 /* gives number of max. msleep()-calls before throwing timeout */
26 #define TPM_MAX_TRIES 5000
27 #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1
29 #define TPM_INF_IO_PORT 0x0
30 #define TPM_INF_IO_MEM 0x1
32 #define TPM_INF_ADDR 0x0
33 #define TPM_INF_DATA 0x1
38 void __iomem
*mem_base
; /* MMIO ioremap'd addr */
39 unsigned long map_base
; /* phys MMIO base */
40 unsigned long map_size
; /* MMIO region size */
41 unsigned int index_off
; /* index register offset */
43 unsigned int data_regs
; /* Data registers */
44 unsigned int data_size
;
46 unsigned int config_port
; /* IO Port config index reg */
47 unsigned int config_size
;
50 static struct tpm_inf_dev tpm_dev
;
52 static inline void tpm_data_out(unsigned char data
, unsigned char offset
)
54 #ifdef CONFIG_HAS_IOPORT
55 if (tpm_dev
.iotype
== TPM_INF_IO_PORT
)
56 outb(data
, tpm_dev
.data_regs
+ offset
);
59 writeb(data
, tpm_dev
.mem_base
+ tpm_dev
.data_regs
+ offset
);
62 static inline unsigned char tpm_data_in(unsigned char offset
)
64 #ifdef CONFIG_HAS_IOPORT
65 if (tpm_dev
.iotype
== TPM_INF_IO_PORT
)
66 return inb(tpm_dev
.data_regs
+ offset
);
68 return readb(tpm_dev
.mem_base
+ tpm_dev
.data_regs
+ offset
);
71 static inline void tpm_config_out(unsigned char data
, unsigned char offset
)
73 #ifdef CONFIG_HAS_IOPORT
74 if (tpm_dev
.iotype
== TPM_INF_IO_PORT
)
75 outb(data
, tpm_dev
.config_port
+ offset
);
78 writeb(data
, tpm_dev
.mem_base
+ tpm_dev
.index_off
+ offset
);
81 static inline unsigned char tpm_config_in(unsigned char offset
)
83 #ifdef CONFIG_HAS_IOPORT
84 if (tpm_dev
.iotype
== TPM_INF_IO_PORT
)
85 return inb(tpm_dev
.config_port
+ offset
);
87 return readb(tpm_dev
.mem_base
+ tpm_dev
.index_off
+ offset
);
90 /* TPM header definitions */
91 enum infineon_tpm_header
{
93 TPM_VL_CHANNEL_CONTROL
= 0x07,
94 TPM_VL_CHANNEL_PERSONALISATION
= 0x0A,
95 TPM_VL_CHANNEL_TPM
= 0x0B,
96 TPM_VL_CONTROL
= 0x00,
99 TPM_CTRL_WTX_ABORT
= 0x18,
100 TPM_CTRL_WTX_ABORT_ACK
= 0x18,
101 TPM_CTRL_ERROR
= 0x20,
102 TPM_CTRL_CHAININGACK
= 0x40,
103 TPM_CTRL_CHAINING
= 0x80,
104 TPM_CTRL_DATA
= 0x04,
105 TPM_CTRL_DATA_CHA
= 0x84,
106 TPM_CTRL_DATA_CHA_ACK
= 0xC4
109 enum infineon_tpm_register
{
116 enum infineon_tpm_command_bits
{
123 enum infineon_tpm_status_bits
{
132 /* some outgoing values */
133 enum infineon_tpm_values
{
137 RESET_LP_IRQC_DISABLE
= 0x41,
138 ENABLE_REGISTER_PAIR
= 0x55,
141 DISABLE_REGISTER_PAIR
= 0xAA,
148 static int number_of_wtx
;
150 static int empty_fifo(struct tpm_chip
*chip
, int clear_wrfifo
)
157 for (i
= 0; i
< 4096; i
++) {
158 status
= tpm_data_in(WRFIFO
);
159 if (status
== 0xff) {
167 /* Note: The values which are currently in the FIFO of the TPM
168 are thrown away since there is no usage for them. Usually,
169 this has nothing to say, since the TPM will give its answer
170 immediately or will be aborted anyway, so the data here is
171 usually garbage and useless.
172 We have to clean this, because the next communication with
173 the TPM would be rubbish, if there is still some old data
178 status
= tpm_data_in(RDFIFO
);
179 status
= tpm_data_in(STAT
);
181 if (i
== TPM_MAX_TRIES
)
183 } while ((status
& (1 << STAT_RDA
)) != 0);
187 static int wait(struct tpm_chip
*chip
, int wait_for_bit
)
191 for (i
= 0; i
< TPM_MAX_TRIES
; i
++) {
192 status
= tpm_data_in(STAT
);
193 /* check the status-register if wait_for_bit is set */
194 if (status
& 1 << wait_for_bit
)
196 tpm_msleep(TPM_MSLEEP_TIME
);
198 if (i
== TPM_MAX_TRIES
) { /* timeout occurs */
199 if (wait_for_bit
== STAT_XFE
)
200 dev_err(&chip
->dev
, "Timeout in wait(STAT_XFE)\n");
201 if (wait_for_bit
== STAT_RDA
)
202 dev_err(&chip
->dev
, "Timeout in wait(STAT_RDA)\n");
208 static void wait_and_send(struct tpm_chip
*chip
, u8 sendbyte
)
210 wait(chip
, STAT_XFE
);
211 tpm_data_out(sendbyte
, WRFIFO
);
214 /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
215 calculation time, it sends a WTX-package, which has to be acknowledged
216 or aborted. This usually occurs if you are hammering the TPM with key
217 creation. Set the maximum number of WTX-packages in the definitions
218 above, if the number is reached, the waiting-time will be denied
219 and the TPM command has to be resend.
222 static void tpm_wtx(struct tpm_chip
*chip
)
225 dev_info(&chip
->dev
, "Granting WTX (%02d / %02d)\n",
226 number_of_wtx
, TPM_MAX_WTX_PACKAGES
);
227 wait_and_send(chip
, TPM_VL_VER
);
228 wait_and_send(chip
, TPM_CTRL_WTX
);
229 wait_and_send(chip
, 0x00);
230 wait_and_send(chip
, 0x00);
231 tpm_msleep(TPM_WTX_MSLEEP_TIME
);
234 static void tpm_wtx_abort(struct tpm_chip
*chip
)
236 dev_info(&chip
->dev
, "Aborting WTX\n");
237 wait_and_send(chip
, TPM_VL_VER
);
238 wait_and_send(chip
, TPM_CTRL_WTX_ABORT
);
239 wait_and_send(chip
, 0x00);
240 wait_and_send(chip
, 0x00);
242 tpm_msleep(TPM_WTX_MSLEEP_TIME
);
245 static int tpm_inf_recv(struct tpm_chip
*chip
, u8
* buf
, size_t count
)
253 /* start receiving header */
254 for (i
= 0; i
< 4; i
++) {
255 ret
= wait(chip
, STAT_RDA
);
258 buf
[i
] = tpm_data_in(RDFIFO
);
261 if (buf
[0] != TPM_VL_VER
) {
263 "Wrong transport protocol implementation!\n");
267 if (buf
[1] == TPM_CTRL_DATA
) {
268 /* size of the data received */
269 size
= ((buf
[2] << 8) | buf
[3]);
271 for (i
= 0; i
< size
; i
++) {
272 wait(chip
, STAT_RDA
);
273 buf
[i
] = tpm_data_in(RDFIFO
);
276 if ((size
== 0x6D00) && (buf
[1] == 0x80)) {
277 dev_err(&chip
->dev
, "Error handling on vendor layer!\n");
281 for (i
= 0; i
< size
; i
++)
288 if (buf
[1] == TPM_CTRL_WTX
) {
289 dev_info(&chip
->dev
, "WTX-package received\n");
290 if (number_of_wtx
< TPM_MAX_WTX_PACKAGES
) {
299 if (buf
[1] == TPM_CTRL_WTX_ABORT_ACK
) {
300 dev_info(&chip
->dev
, "WTX-abort acknowledged\n");
304 if (buf
[1] == TPM_CTRL_ERROR
) {
305 dev_err(&chip
->dev
, "ERROR-package received:\n");
306 if (buf
[4] == TPM_INF_NAK
)
308 "-> Negative acknowledgement"
309 " - retransmit command!\n");
315 static int tpm_inf_send(struct tpm_chip
*chip
, u8
* buf
, size_t count
)
319 u8 count_high
, count_low
, count_4
, count_3
, count_2
, count_1
;
321 /* Disabling Reset, LP and IRQC */
322 tpm_data_out(RESET_LP_IRQC_DISABLE
, CMD
);
324 ret
= empty_fifo(chip
, 1);
326 dev_err(&chip
->dev
, "Timeout while clearing FIFO\n");
330 ret
= wait(chip
, STAT_XFE
);
334 count_4
= (count
& 0xff000000) >> 24;
335 count_3
= (count
& 0x00ff0000) >> 16;
336 count_2
= (count
& 0x0000ff00) >> 8;
337 count_1
= (count
& 0x000000ff);
338 count_high
= ((count
+ 6) & 0xffffff00) >> 8;
339 count_low
= ((count
+ 6) & 0x000000ff);
342 wait_and_send(chip
, TPM_VL_VER
);
343 wait_and_send(chip
, TPM_CTRL_DATA
);
344 wait_and_send(chip
, count_high
);
345 wait_and_send(chip
, count_low
);
347 /* Sending Data Header */
348 wait_and_send(chip
, TPM_VL_VER
);
349 wait_and_send(chip
, TPM_VL_CHANNEL_TPM
);
350 wait_and_send(chip
, count_4
);
351 wait_and_send(chip
, count_3
);
352 wait_and_send(chip
, count_2
);
353 wait_and_send(chip
, count_1
);
356 for (i
= 0; i
< count
; i
++) {
357 wait_and_send(chip
, buf
[i
]);
362 static void tpm_inf_cancel(struct tpm_chip
*chip
)
365 Since we are using the legacy mode to communicate
366 with the TPM, we have no cancel functions, but have
367 a workaround for interrupting the TPM through WTX.
371 static u8
tpm_inf_status(struct tpm_chip
*chip
)
373 return tpm_data_in(STAT
);
376 static const struct tpm_class_ops tpm_inf
= {
377 .recv
= tpm_inf_recv
,
378 .send
= tpm_inf_send
,
379 .cancel
= tpm_inf_cancel
,
380 .status
= tpm_inf_status
,
381 .req_complete_mask
= 0,
382 .req_complete_val
= 0,
385 static const struct pnp_device_id tpm_inf_pnp_tbl
[] = {
392 MODULE_DEVICE_TABLE(pnp
, tpm_inf_pnp_tbl
);
394 static int tpm_inf_pnp_probe(struct pnp_dev
*dev
,
395 const struct pnp_device_id
*dev_id
)
402 const char *chipname
;
403 struct tpm_chip
*chip
;
405 /* read IO-ports through PnP */
406 if (pnp_port_valid(dev
, 0) && pnp_port_valid(dev
, 1) &&
407 !(pnp_port_flags(dev
, 0) & IORESOURCE_DISABLED
)) {
409 tpm_dev
.iotype
= TPM_INF_IO_PORT
;
411 tpm_dev
.config_port
= pnp_port_start(dev
, 0);
412 tpm_dev
.config_size
= pnp_port_len(dev
, 0);
413 tpm_dev
.data_regs
= pnp_port_start(dev
, 1);
414 tpm_dev
.data_size
= pnp_port_len(dev
, 1);
415 if ((tpm_dev
.data_size
< 4) || (tpm_dev
.config_size
< 2)) {
419 dev_info(&dev
->dev
, "Found %s with ID %s\n",
420 dev
->name
, dev_id
->id
);
421 if (!((tpm_dev
.data_regs
>> 8) & 0xff)) {
425 /* publish my base address and request region */
426 if (request_region(tpm_dev
.data_regs
, tpm_dev
.data_size
,
427 "tpm_infineon0") == NULL
) {
431 if (request_region(tpm_dev
.config_port
, tpm_dev
.config_size
,
432 "tpm_infineon0") == NULL
) {
433 release_region(tpm_dev
.data_regs
, tpm_dev
.data_size
);
437 } else if (pnp_mem_valid(dev
, 0) &&
438 !(pnp_mem_flags(dev
, 0) & IORESOURCE_DISABLED
)) {
440 tpm_dev
.iotype
= TPM_INF_IO_MEM
;
442 tpm_dev
.map_base
= pnp_mem_start(dev
, 0);
443 tpm_dev
.map_size
= pnp_mem_len(dev
, 0);
445 dev_info(&dev
->dev
, "Found %s with ID %s\n",
446 dev
->name
, dev_id
->id
);
448 /* publish my base address and request region */
449 if (request_mem_region(tpm_dev
.map_base
, tpm_dev
.map_size
,
450 "tpm_infineon0") == NULL
) {
455 tpm_dev
.mem_base
= ioremap(tpm_dev
.map_base
, tpm_dev
.map_size
);
456 if (tpm_dev
.mem_base
== NULL
) {
457 release_mem_region(tpm_dev
.map_base
, tpm_dev
.map_size
);
463 * The only known MMIO based Infineon TPM system provides
464 * a single large mem region with the device config
465 * registers at the default TPM_ADDR. The data registers
466 * seem like they could be placed anywhere within the MMIO
467 * region, but lets just put them at zero offset.
469 tpm_dev
.index_off
= TPM_ADDR
;
470 tpm_dev
.data_regs
= 0x0;
476 /* query chip for its vendor, its version number a.s.o. */
477 tpm_config_out(ENABLE_REGISTER_PAIR
, TPM_INF_ADDR
);
478 tpm_config_out(IDVENL
, TPM_INF_ADDR
);
479 vendorid
[1] = tpm_config_in(TPM_INF_DATA
);
480 tpm_config_out(IDVENH
, TPM_INF_ADDR
);
481 vendorid
[0] = tpm_config_in(TPM_INF_DATA
);
482 tpm_config_out(IDPDL
, TPM_INF_ADDR
);
483 productid
[1] = tpm_config_in(TPM_INF_DATA
);
484 tpm_config_out(IDPDH
, TPM_INF_ADDR
);
485 productid
[0] = tpm_config_in(TPM_INF_DATA
);
486 tpm_config_out(CHIP_ID1
, TPM_INF_ADDR
);
487 version
[1] = tpm_config_in(TPM_INF_DATA
);
488 tpm_config_out(CHIP_ID2
, TPM_INF_ADDR
);
489 version
[0] = tpm_config_in(TPM_INF_DATA
);
491 switch ((productid
[0] << 8) | productid
[1]) {
493 chipname
= " (SLD 9630 TT 1.1)";
496 chipname
= " (SLB 9635 TT 1.2)";
499 chipname
= " (unknown chip)";
503 if ((vendorid
[0] << 8 | vendorid
[1]) == (TPM_INFINEON_DEV_VEN_VALUE
)) {
505 /* configure TPM with IO-ports */
506 tpm_config_out(IOLIMH
, TPM_INF_ADDR
);
507 tpm_config_out((tpm_dev
.data_regs
>> 8) & 0xff, TPM_INF_DATA
);
508 tpm_config_out(IOLIML
, TPM_INF_ADDR
);
509 tpm_config_out((tpm_dev
.data_regs
& 0xff), TPM_INF_DATA
);
511 /* control if IO-ports are set correctly */
512 tpm_config_out(IOLIMH
, TPM_INF_ADDR
);
513 ioh
= tpm_config_in(TPM_INF_DATA
);
514 tpm_config_out(IOLIML
, TPM_INF_ADDR
);
515 iol
= tpm_config_in(TPM_INF_DATA
);
517 if ((ioh
<< 8 | iol
) != tpm_dev
.data_regs
) {
519 "Could not set IO-data registers to 0x%x\n",
522 goto err_release_region
;
525 /* activate register */
526 tpm_config_out(TPM_DAR
, TPM_INF_ADDR
);
527 tpm_config_out(0x01, TPM_INF_DATA
);
528 tpm_config_out(DISABLE_REGISTER_PAIR
, TPM_INF_ADDR
);
530 /* disable RESET, LP and IRQC */
531 tpm_data_out(RESET_LP_IRQC_DISABLE
, CMD
);
533 /* Finally, we're done, print some infos */
534 dev_info(&dev
->dev
, "TPM found: "
535 "config base 0x%lx, "
537 "chip version 0x%02x%02x, "
538 "vendor id 0x%x%x (Infineon), "
539 "product id 0x%02x%02x"
541 tpm_dev
.iotype
== TPM_INF_IO_PORT
?
542 tpm_dev
.config_port
:
543 tpm_dev
.map_base
+ tpm_dev
.index_off
,
544 tpm_dev
.iotype
== TPM_INF_IO_PORT
?
546 tpm_dev
.map_base
+ tpm_dev
.data_regs
,
547 version
[0], version
[1],
548 vendorid
[0], vendorid
[1],
549 productid
[0], productid
[1], chipname
);
551 chip
= tpmm_chip_alloc(&dev
->dev
, &tpm_inf
);
554 goto err_release_region
;
557 rc
= tpm_chip_register(chip
);
559 goto err_release_region
;
564 goto err_release_region
;
568 if (tpm_dev
.iotype
== TPM_INF_IO_PORT
) {
569 release_region(tpm_dev
.data_regs
, tpm_dev
.data_size
);
570 release_region(tpm_dev
.config_port
, tpm_dev
.config_size
);
572 iounmap(tpm_dev
.mem_base
);
573 release_mem_region(tpm_dev
.map_base
, tpm_dev
.map_size
);
580 static void tpm_inf_pnp_remove(struct pnp_dev
*dev
)
582 struct tpm_chip
*chip
= pnp_get_drvdata(dev
);
584 tpm_chip_unregister(chip
);
586 if (tpm_dev
.iotype
== TPM_INF_IO_PORT
) {
587 release_region(tpm_dev
.data_regs
, tpm_dev
.data_size
);
588 release_region(tpm_dev
.config_port
,
589 tpm_dev
.config_size
);
591 iounmap(tpm_dev
.mem_base
);
592 release_mem_region(tpm_dev
.map_base
, tpm_dev
.map_size
);
596 #ifdef CONFIG_PM_SLEEP
597 static int tpm_inf_resume(struct device
*dev
)
599 /* Re-configure TPM after suspending */
600 tpm_config_out(ENABLE_REGISTER_PAIR
, TPM_INF_ADDR
);
601 tpm_config_out(IOLIMH
, TPM_INF_ADDR
);
602 tpm_config_out((tpm_dev
.data_regs
>> 8) & 0xff, TPM_INF_DATA
);
603 tpm_config_out(IOLIML
, TPM_INF_ADDR
);
604 tpm_config_out((tpm_dev
.data_regs
& 0xff), TPM_INF_DATA
);
605 /* activate register */
606 tpm_config_out(TPM_DAR
, TPM_INF_ADDR
);
607 tpm_config_out(0x01, TPM_INF_DATA
);
608 tpm_config_out(DISABLE_REGISTER_PAIR
, TPM_INF_ADDR
);
609 /* disable RESET, LP and IRQC */
610 tpm_data_out(RESET_LP_IRQC_DISABLE
, CMD
);
611 return tpm_pm_resume(dev
);
614 static SIMPLE_DEV_PM_OPS(tpm_inf_pm
, tpm_pm_suspend
, tpm_inf_resume
);
616 static struct pnp_driver tpm_inf_pnp_driver
= {
617 .name
= "tpm_inf_pnp",
618 .id_table
= tpm_inf_pnp_tbl
,
619 .probe
= tpm_inf_pnp_probe
,
620 .remove
= tpm_inf_pnp_remove
,
626 module_pnp_driver(tpm_inf_pnp_driver
);
628 MODULE_AUTHOR("Marcel Selhorst <tpmdd@sirrix.com>");
629 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
630 MODULE_VERSION("1.9.2");
631 MODULE_LICENSE("GPL");