Commit 1b393db5870927d68c42a46e6c5877c8d0d83910

Authored by Tom Wai-Hong Tam
Committed by Simon Glass
1 parent ec34fa5e43

tpm: Reorganize the I2C TPM driver

This patch does a similar code reogranzation from
  http://patchwork.ozlabs.org/patch/132179/
which is based on an old version of code (fdt support and bus selection
still not in). It merges this tidy-up on top of the recent code. It does
not make any logical change.

tpm.c implements the interface defined in tpm.h based on underlying
LPC or I2C TPM driver. tpm.c and the underlying driver communicate
throught tpm_private.h.

Note: Merging the LPC driver with tpm.c is left to future patches.

Change-Id: Ie1384f5f9e3935d3bc9a44adf8de80c5a70a5f2b
Signed-off-by: Tom Wai-Hong Tam <waihong@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Simon Glass <sjg@chromium.org>

Showing 10 changed files with 1423 additions and 1295 deletions Side-by-side Diff

... ... @@ -1212,6 +1212,19 @@
1212 1212 CONFIG_TPM
1213 1213 Support TPM devices.
1214 1214  
  1215 + CONFIG_TPM_TIS_I2C
  1216 + Support for i2c bus TPM devices. Only one device
  1217 + per system is supported at this time.
  1218 +
  1219 + CONFIG_TPM_TIS_I2C_BUS_NUMBER
  1220 + Define the the i2c bus number for the TPM device
  1221 +
  1222 + CONFIG_TPM_TIS_I2C_SLAVE_ADDRESS
  1223 + Define the TPM's address on the i2c bus
  1224 +
  1225 + CONFIG_TPM_TIS_I2C_BURST_LIMITATION
  1226 + Define the burst count bytes upper limit
  1227 +
1215 1228 CONFIG_TPM_TIS_LPC
1216 1229 Support for generic parallel port TPM devices. Only one device
1217 1230 per system is supported at this time.
drivers/tpm/Makefile
... ... @@ -25,9 +25,10 @@
25 25  
26 26 $(shell mkdir -p $(obj)slb9635_i2c)
27 27  
28   -COBJS-$(CONFIG_TPM_TIS_LPC) = tpm_tis_lpc.o
29   -COBJS-$(CONFIG_INFINEON_TPM_I2C) += tis_i2c.o slb9635_i2c/tpm.o
30   -COBJS-$(CONFIG_INFINEON_TPM_I2C) += slb9635_i2c/tpm_tis_i2c.o
  28 +# TODO: Merge tpm_tis_lpc.c with tpm.c
  29 +COBJS-$(CONFIG_TPM_TIS_I2C) += tpm.o
  30 +COBJS-$(CONFIG_TPM_TIS_I2C) += tpm_tis_i2c.o
  31 +COBJS-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o
31 32  
32 33 COBJS := $(COBJS-y)
33 34 SRCS := $(COBJS:.o=.c)
drivers/tpm/slb9635_i2c/compatibility.h
1   -/*
2   - * Copyright (C) 2011 Infineon Technologies
3   - *
4   - * Authors:
5   - * Peter Huewe <huewe.external@infineon.com>
6   - *
7   - * Version: 2.1.1
8   - *
9   - * See file CREDITS for list of people who contributed to this
10   - * project.
11   - *
12   - * This program is free software; you can redistribute it and/or
13   - * modify it under the terms of the GNU General Public License as
14   - * published by the Free Software Foundation; either version 2 of
15   - * the License, or (at your option) any later version.
16   - *
17   - * This program is distributed in the hope that it will be useful,
18   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
19   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20   - * GNU General Public License for more details.
21   - *
22   - * You should have received a copy of the GNU General Public License
23   - * along with this program; if not, write to the Free Software
24   - * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25   - * MA 02111-1307 USA
26   - */
27   -
28   -#ifndef _COMPATIBILITY_H_
29   -#define _COMPATIBILITY_H_
30   -
31   -/* all includes from U-Boot */
32   -#include <linux/types.h>
33   -#include <linux/unaligned/be_byteshift.h>
34   -#include <asm-generic/errno.h>
35   -#include <compiler.h>
36   -#include <common.h>
37   -
38   -/* extended error numbers from linux (see errno.h) */
39   -#define ECANCELED 125 /* Operation Canceled */
40   -
41   -#define msleep(t) udelay((t)*1000)
42   -
43   -/* Timer frequency. Corresponds to msec timer resolution*/
44   -#define HZ 1000
45   -
46   -#define dev_dbg(dev, format, arg...) debug(format, ##arg)
47   -#define dev_err(dev, format, arg...) printf(format, ##arg)
48   -#define dev_info(dev, format, arg...) debug(format, ##arg)
49   -#define dbg_printf debug
50   -
51   -#endif
drivers/tpm/slb9635_i2c/tpm.c
1   -/*
2   - * Copyright (C) 2011 Infineon Technologies
3   - *
4   - * Authors:
5   - * Peter Huewe <huewe.external@infineon.com>
6   - *
7   - * Description:
8   - * Device driver for TCG/TCPA TPM (trusted platform module).
9   - * Specifications at www.trustedcomputinggroup.org
10   - *
11   - * It is based on the Linux kernel driver tpm.c from Leendert van
12   - * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
13   - *
14   - * Version: 2.1.1
15   - *
16   - * See file CREDITS for list of people who contributed to this
17   - * project.
18   - *
19   - * This program is free software; you can redistribute it and/or
20   - * modify it under the terms of the GNU General Public License as
21   - * published by the Free Software Foundation, version 2 of the
22   - * License.
23   - *
24   - * This program is distributed in the hope that it will be useful,
25   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
26   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27   - * GNU General Public License for more details.
28   - *
29   - * You should have received a copy of the GNU General Public License
30   - * along with this program; if not, write to the Free Software
31   - * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32   - * MA 02111-1307 USA
33   - */
34   -
35   -#include <malloc.h>
36   -#include "tpm.h"
37   -
38   -/* global structure for tpm chip data */
39   -struct tpm_chip g_chip;
40   -
41   -enum tpm_duration {
42   - TPM_SHORT = 0,
43   - TPM_MEDIUM = 1,
44   - TPM_LONG = 2,
45   - TPM_UNDEFINED,
46   -};
47   -
48   -#define TPM_MAX_ORDINAL 243
49   -#define TPM_MAX_PROTECTED_ORDINAL 12
50   -#define TPM_PROTECTED_ORDINAL_MASK 0xFF
51   -
52   -/*
53   - * Array with one entry per ordinal defining the maximum amount
54   - * of time the chip could take to return the result. The ordinal
55   - * designation of short, medium or long is defined in a table in
56   - * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
57   - * values of the SHORT, MEDIUM, and LONG durations are retrieved
58   - * from the chip during initialization with a call to tpm_get_timeouts.
59   - */
60   -static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
61   - TPM_UNDEFINED, /* 0 */
62   - TPM_UNDEFINED,
63   - TPM_UNDEFINED,
64   - TPM_UNDEFINED,
65   - TPM_UNDEFINED,
66   - TPM_UNDEFINED, /* 5 */
67   - TPM_UNDEFINED,
68   - TPM_UNDEFINED,
69   - TPM_UNDEFINED,
70   - TPM_UNDEFINED,
71   - TPM_SHORT, /* 10 */
72   - TPM_SHORT,
73   -};
74   -
75   -static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
76   - TPM_UNDEFINED, /* 0 */
77   - TPM_UNDEFINED,
78   - TPM_UNDEFINED,
79   - TPM_UNDEFINED,
80   - TPM_UNDEFINED,
81   - TPM_UNDEFINED, /* 5 */
82   - TPM_UNDEFINED,
83   - TPM_UNDEFINED,
84   - TPM_UNDEFINED,
85   - TPM_UNDEFINED,
86   - TPM_SHORT, /* 10 */
87   - TPM_SHORT,
88   - TPM_MEDIUM,
89   - TPM_LONG,
90   - TPM_LONG,
91   - TPM_MEDIUM, /* 15 */
92   - TPM_SHORT,
93   - TPM_SHORT,
94   - TPM_MEDIUM,
95   - TPM_LONG,
96   - TPM_SHORT, /* 20 */
97   - TPM_SHORT,
98   - TPM_MEDIUM,
99   - TPM_MEDIUM,
100   - TPM_MEDIUM,
101   - TPM_SHORT, /* 25 */
102   - TPM_SHORT,
103   - TPM_MEDIUM,
104   - TPM_SHORT,
105   - TPM_SHORT,
106   - TPM_MEDIUM, /* 30 */
107   - TPM_LONG,
108   - TPM_MEDIUM,
109   - TPM_SHORT,
110   - TPM_SHORT,
111   - TPM_SHORT, /* 35 */
112   - TPM_MEDIUM,
113   - TPM_MEDIUM,
114   - TPM_UNDEFINED,
115   - TPM_UNDEFINED,
116   - TPM_MEDIUM, /* 40 */
117   - TPM_LONG,
118   - TPM_MEDIUM,
119   - TPM_SHORT,
120   - TPM_SHORT,
121   - TPM_SHORT, /* 45 */
122   - TPM_SHORT,
123   - TPM_SHORT,
124   - TPM_SHORT,
125   - TPM_LONG,
126   - TPM_MEDIUM, /* 50 */
127   - TPM_MEDIUM,
128   - TPM_UNDEFINED,
129   - TPM_UNDEFINED,
130   - TPM_UNDEFINED,
131   - TPM_UNDEFINED, /* 55 */
132   - TPM_UNDEFINED,
133   - TPM_UNDEFINED,
134   - TPM_UNDEFINED,
135   - TPM_UNDEFINED,
136   - TPM_MEDIUM, /* 60 */
137   - TPM_MEDIUM,
138   - TPM_MEDIUM,
139   - TPM_SHORT,
140   - TPM_SHORT,
141   - TPM_MEDIUM, /* 65 */
142   - TPM_UNDEFINED,
143   - TPM_UNDEFINED,
144   - TPM_UNDEFINED,
145   - TPM_UNDEFINED,
146   - TPM_SHORT, /* 70 */
147   - TPM_SHORT,
148   - TPM_UNDEFINED,
149   - TPM_UNDEFINED,
150   - TPM_UNDEFINED,
151   - TPM_UNDEFINED, /* 75 */
152   - TPM_UNDEFINED,
153   - TPM_UNDEFINED,
154   - TPM_UNDEFINED,
155   - TPM_UNDEFINED,
156   - TPM_LONG, /* 80 */
157   - TPM_UNDEFINED,
158   - TPM_MEDIUM,
159   - TPM_LONG,
160   - TPM_SHORT,
161   - TPM_UNDEFINED, /* 85 */
162   - TPM_UNDEFINED,
163   - TPM_UNDEFINED,
164   - TPM_UNDEFINED,
165   - TPM_UNDEFINED,
166   - TPM_SHORT, /* 90 */
167   - TPM_SHORT,
168   - TPM_SHORT,
169   - TPM_SHORT,
170   - TPM_SHORT,
171   - TPM_UNDEFINED, /* 95 */
172   - TPM_UNDEFINED,
173   - TPM_UNDEFINED,
174   - TPM_UNDEFINED,
175   - TPM_UNDEFINED,
176   - TPM_MEDIUM, /* 100 */
177   - TPM_SHORT,
178   - TPM_SHORT,
179   - TPM_UNDEFINED,
180   - TPM_UNDEFINED,
181   - TPM_UNDEFINED, /* 105 */
182   - TPM_UNDEFINED,
183   - TPM_UNDEFINED,
184   - TPM_UNDEFINED,
185   - TPM_UNDEFINED,
186   - TPM_SHORT, /* 110 */
187   - TPM_SHORT,
188   - TPM_SHORT,
189   - TPM_SHORT,
190   - TPM_SHORT,
191   - TPM_SHORT, /* 115 */
192   - TPM_SHORT,
193   - TPM_SHORT,
194   - TPM_UNDEFINED,
195   - TPM_UNDEFINED,
196   - TPM_LONG, /* 120 */
197   - TPM_LONG,
198   - TPM_MEDIUM,
199   - TPM_UNDEFINED,
200   - TPM_SHORT,
201   - TPM_SHORT, /* 125 */
202   - TPM_SHORT,
203   - TPM_LONG,
204   - TPM_SHORT,
205   - TPM_SHORT,
206   - TPM_SHORT, /* 130 */
207   - TPM_MEDIUM,
208   - TPM_UNDEFINED,
209   - TPM_SHORT,
210   - TPM_MEDIUM,
211   - TPM_UNDEFINED, /* 135 */
212   - TPM_UNDEFINED,
213   - TPM_UNDEFINED,
214   - TPM_UNDEFINED,
215   - TPM_UNDEFINED,
216   - TPM_SHORT, /* 140 */
217   - TPM_SHORT,
218   - TPM_UNDEFINED,
219   - TPM_UNDEFINED,
220   - TPM_UNDEFINED,
221   - TPM_UNDEFINED, /* 145 */
222   - TPM_UNDEFINED,
223   - TPM_UNDEFINED,
224   - TPM_UNDEFINED,
225   - TPM_UNDEFINED,
226   - TPM_SHORT, /* 150 */
227   - TPM_MEDIUM,
228   - TPM_MEDIUM,
229   - TPM_SHORT,
230   - TPM_SHORT,
231   - TPM_UNDEFINED, /* 155 */
232   - TPM_UNDEFINED,
233   - TPM_UNDEFINED,
234   - TPM_UNDEFINED,
235   - TPM_UNDEFINED,
236   - TPM_SHORT, /* 160 */
237   - TPM_SHORT,
238   - TPM_SHORT,
239   - TPM_SHORT,
240   - TPM_UNDEFINED,
241   - TPM_UNDEFINED, /* 165 */
242   - TPM_UNDEFINED,
243   - TPM_UNDEFINED,
244   - TPM_UNDEFINED,
245   - TPM_UNDEFINED,
246   - TPM_LONG, /* 170 */
247   - TPM_UNDEFINED,
248   - TPM_UNDEFINED,
249   - TPM_UNDEFINED,
250   - TPM_UNDEFINED,
251   - TPM_UNDEFINED, /* 175 */
252   - TPM_UNDEFINED,
253   - TPM_UNDEFINED,
254   - TPM_UNDEFINED,
255   - TPM_UNDEFINED,
256   - TPM_MEDIUM, /* 180 */
257   - TPM_SHORT,
258   - TPM_MEDIUM,
259   - TPM_MEDIUM,
260   - TPM_MEDIUM,
261   - TPM_MEDIUM, /* 185 */
262   - TPM_SHORT,
263   - TPM_UNDEFINED,
264   - TPM_UNDEFINED,
265   - TPM_UNDEFINED,
266   - TPM_UNDEFINED, /* 190 */
267   - TPM_UNDEFINED,
268   - TPM_UNDEFINED,
269   - TPM_UNDEFINED,
270   - TPM_UNDEFINED,
271   - TPM_UNDEFINED, /* 195 */
272   - TPM_UNDEFINED,
273   - TPM_UNDEFINED,
274   - TPM_UNDEFINED,
275   - TPM_UNDEFINED,
276   - TPM_SHORT, /* 200 */
277   - TPM_UNDEFINED,
278   - TPM_UNDEFINED,
279   - TPM_UNDEFINED,
280   - TPM_SHORT,
281   - TPM_SHORT, /* 205 */
282   - TPM_SHORT,
283   - TPM_SHORT,
284   - TPM_SHORT,
285   - TPM_SHORT,
286   - TPM_MEDIUM, /* 210 */
287   - TPM_UNDEFINED,
288   - TPM_MEDIUM,
289   - TPM_MEDIUM,
290   - TPM_MEDIUM,
291   - TPM_UNDEFINED, /* 215 */
292   - TPM_MEDIUM,
293   - TPM_UNDEFINED,
294   - TPM_UNDEFINED,
295   - TPM_SHORT,
296   - TPM_SHORT, /* 220 */
297   - TPM_SHORT,
298   - TPM_SHORT,
299   - TPM_SHORT,
300   - TPM_SHORT,
301   - TPM_UNDEFINED, /* 225 */
302   - TPM_UNDEFINED,
303   - TPM_UNDEFINED,
304   - TPM_UNDEFINED,
305   - TPM_UNDEFINED,
306   - TPM_SHORT, /* 230 */
307   - TPM_LONG,
308   - TPM_MEDIUM,
309   - TPM_UNDEFINED,
310   - TPM_UNDEFINED,
311   - TPM_UNDEFINED, /* 235 */
312   - TPM_UNDEFINED,
313   - TPM_UNDEFINED,
314   - TPM_UNDEFINED,
315   - TPM_UNDEFINED,
316   - TPM_SHORT, /* 240 */
317   - TPM_UNDEFINED,
318   - TPM_MEDIUM,
319   -};
320   -
321   -/*
322   - * Returns max number of milliseconds to wait
323   - */
324   -unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
325   -{
326   - int duration_idx = TPM_UNDEFINED;
327   - int duration = 0;
328   -
329   - if (ordinal < TPM_MAX_ORDINAL)
330   - duration_idx = tpm_ordinal_duration[ordinal];
331   - else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
332   - TPM_MAX_PROTECTED_ORDINAL)
333   - duration_idx =
334   - tpm_protected_ordinal_duration[ordinal &
335   - TPM_PROTECTED_ORDINAL_MASK];
336   -
337   - if (duration_idx != TPM_UNDEFINED)
338   - duration = chip->vendor.duration[duration_idx];
339   - if (duration <= 0)
340   - return 2 * 60 * HZ; /*two minutes timeout*/
341   - else
342   - return duration;
343   -}
344   -
345   -#define TPM_CMD_COUNT_BYTE 2
346   -#define TPM_CMD_ORDINAL_BYTE 6
347   -
348   -ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
349   -{
350   - ssize_t rc;
351   - u32 count, ordinal;
352   - unsigned long start, stop;
353   -
354   - struct tpm_chip *chip = &g_chip;
355   -
356   - /* switch endianess: big->little */
357   - count = get_unaligned_be32(buf + TPM_CMD_COUNT_BYTE);
358   - ordinal = get_unaligned_be32(buf + TPM_CMD_ORDINAL_BYTE);
359   -
360   - if (count == 0) {
361   - dev_err(chip->dev, "no data\n");
362   - return -ENODATA;
363   - }
364   - if (count > bufsiz) {
365   - dev_err(chip->dev,
366   - "invalid count value %x %zx\n", count, bufsiz);
367   - return -E2BIG;
368   - }
369   -
370   - rc = chip->vendor.send(chip, (u8 *)buf, count);
371   - if (rc < 0) {
372   - dev_err(chip->dev, "tpm_transmit: tpm_send: error %zd\n", rc);
373   - goto out;
374   - }
375   -
376   - if (chip->vendor.irq)
377   - goto out_recv;
378   -
379   - start = get_timer(0);
380   - stop = tpm_calc_ordinal_duration(chip, ordinal);
381   - do {
382   - dbg_printf("waiting for status...\n");
383   - u8 status = chip->vendor.status(chip);
384   - if ((status & chip->vendor.req_complete_mask) ==
385   - chip->vendor.req_complete_val) {
386   - dbg_printf("...got it;\n");
387   - goto out_recv;
388   - }
389   -
390   - if ((status == chip->vendor.req_canceled)) {
391   - dev_err(chip->dev, "Operation Canceled\n");
392   - rc = -ECANCELED;
393   - goto out;
394   - }
395   - msleep(TPM_TIMEOUT);
396   - } while (get_timer(start) < stop);
397   -
398   - chip->vendor.cancel(chip);
399   - dev_err(chip->dev, "Operation Timed out\n");
400   - rc = -ETIME;
401   - goto out;
402   -
403   -out_recv:
404   -
405   - dbg_printf("out_recv: reading response...\n");
406   - rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE);
407   - if (rc < 0)
408   - dev_err(chip->dev, "tpm_transmit: tpm_recv: error %zd\n", rc);
409   -out:
410   - return rc;
411   -}
412   -
413   -#define TPM_ERROR_SIZE 10
414   -
415   -enum tpm_capabilities {
416   - TPM_CAP_PROP = cpu_to_be32(5),
417   -};
418   -
419   -enum tpm_sub_capabilities {
420   - TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
421   - TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
422   -};
423   -
424   -struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *entry)
425   -{
426   - struct tpm_chip *chip;
427   -
428   - /* Driver specific per-device data */
429   - chip = &g_chip;
430   - memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
431   - chip->is_open = 1;
432   -
433   - return chip;
434   -}
435   -
436   -int tpm_open(uint32_t dev_addr)
437   -{
438   - int rc;
439   - if (g_chip.is_open)
440   - return -EBUSY;
441   - rc = tpm_vendor_init(dev_addr);
442   - if (rc < 0)
443   - g_chip.is_open = 0;
444   - return rc;
445   -}
446   -
447   -void tpm_close(void)
448   -{
449   - if (g_chip.is_open) {
450   - tpm_vendor_cleanup(&g_chip);
451   - g_chip.is_open = 0;
452   - }
453   -}
drivers/tpm/slb9635_i2c/tpm.h
1   -/*
2   - * Copyright (C) 2011 Infineon Technologies
3   - *
4   - * Authors:
5   - * Peter Huewe <huewe.external@infineon.com>
6   - *
7   - * Version: 2.1.1
8   - *
9   - * Description:
10   - * Device driver for TCG/TCPA TPM (trusted platform module).
11   - * Specifications at www.trustedcomputinggroup.org
12   - *
13   - * It is based on the Linux kernel driver tpm.c from Leendert van
14   - * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
15   - *
16   - *
17   - * See file CREDITS for list of people who contributed to this
18   - * project.
19   - *
20   - * This program is free software; you can redistribute it and/or
21   - * modify it under the terms of the GNU General Public License as
22   - * published by the Free Software Foundation, version 2 of the
23   - * License.
24   - *
25   - * This program is distributed in the hope that it will be useful,
26   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
27   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28   - * GNU General Public License for more details.
29   - *
30   - * You should have received a copy of the GNU General Public License
31   - * along with this program; if not, write to the Free Software
32   - * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
33   - * MA 02111-1307 USA
34   - */
35   -
36   -#ifndef _TPM_H_
37   -#define _TPM_H_
38   -
39   -#include <linux/compiler.h>
40   -
41   -#include "compatibility.h"
42   -
43   -enum tpm_timeout {
44   - TPM_TIMEOUT = 5, /* msecs */
45   -};
46   -
47   -/* Size of external transmit buffer (used in tpm_transmit)*/
48   -#define TPM_BUFSIZE 4096
49   -
50   -/* Index of fields in TPM command buffer */
51   -#define TPM_CMD_SIZE_BYTE 2
52   -#define TPM_CMD_ORDINAL_BYTE 6
53   -
54   -/* Index of Count field in TPM response buffer */
55   -#define TPM_RSP_SIZE_BYTE 2
56   -#define TPM_RSP_RC_BYTE 6
57   -
58   -struct tpm_chip;
59   -
60   -struct tpm_vendor_specific {
61   - const u8 req_complete_mask;
62   - const u8 req_complete_val;
63   - const u8 req_canceled;
64   - int irq;
65   - int (*recv) (struct tpm_chip *, u8 *, size_t);
66   - int (*send) (struct tpm_chip *, u8 *, size_t);
67   - void (*cancel) (struct tpm_chip *);
68   - u8(*status) (struct tpm_chip *);
69   - int locality;
70   - unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* msec */
71   - unsigned long duration[3]; /* msec */
72   -};
73   -
74   -struct tpm_chip {
75   - int is_open;
76   - struct tpm_vendor_specific vendor;
77   -};
78   -
79   -struct tpm_input_header {
80   - __be16 tag;
81   - __be32 length;
82   - __be32 ordinal;
83   -} __packed;
84   -
85   -struct tpm_output_header {
86   - __be16 tag;
87   - __be32 length;
88   - __be32 return_code;
89   -} __packed;
90   -
91   -struct timeout_t {
92   - __be32 a;
93   - __be32 b;
94   - __be32 c;
95   - __be32 d;
96   -} __packed;
97   -
98   -struct duration_t {
99   - __be32 tpm_short;
100   - __be32 tpm_medium;
101   - __be32 tpm_long;
102   -} __packed;
103   -
104   -union cap_t {
105   - struct timeout_t timeout;
106   - struct duration_t duration;
107   -};
108   -
109   -struct tpm_getcap_params_in {
110   - __be32 cap;
111   - __be32 subcap_size;
112   - __be32 subcap;
113   -} __packed;
114   -
115   -struct tpm_getcap_params_out {
116   - __be32 cap_size;
117   - union cap_t cap;
118   -} __packed;
119   -
120   -union tpm_cmd_header {
121   - struct tpm_input_header in;
122   - struct tpm_output_header out;
123   -};
124   -
125   -union tpm_cmd_params {
126   - struct tpm_getcap_params_out getcap_out;
127   - struct tpm_getcap_params_in getcap_in;
128   -};
129   -
130   -struct tpm_cmd_t {
131   - union tpm_cmd_header header;
132   - union tpm_cmd_params params;
133   -} __packed;
134   -
135   -
136   -/* ---------- Interface for TPM vendor ------------ */
137   -
138   -extern struct tpm_chip *tpm_register_hardware(
139   - const struct tpm_vendor_specific *);
140   -
141   -extern int tpm_vendor_init(uint32_t dev_addr);
142   -
143   -extern void tpm_vendor_cleanup(struct tpm_chip *chip);
144   -
145   -/* ---------- Interface for TDDL ------------------- */
146   -
147   -/*
148   - * if dev_addr != 0 - redefines TPM device address
149   - * Returns < 0 on error, 0 on success.
150   - */
151   -extern int tpm_open(uint32_t dev_addr);
152   -
153   -extern void tpm_close(void);
154   -
155   -/*
156   - * Transmit bufsiz bytes out of buf to TPM and get results back in buf, too.
157   - * Returns < 0 on error, 0 on success.
158   - */
159   -extern ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz);
160   -
161   -#endif
drivers/tpm/slb9635_i2c/tpm_tis_i2c.c
1   -/*
2   - * Copyright (C) 2011 Infineon Technologies
3   - *
4   - * Authors:
5   - * Peter Huewe <huewe.external@infineon.com>
6   - *
7   - * Description:
8   - * Device driver for TCG/TCPA TPM (trusted platform module).
9   - * Specifications at www.trustedcomputinggroup.org
10   - *
11   - * This device driver implements the TPM interface as defined in
12   - * the TCG TPM Interface Spec version 1.2, revision 1.0 and the
13   - * Infineon I2C Protocol Stack Specification v0.20.
14   - *
15   - * It is based on the Linux kernel driver tpm.c from Leendert van
16   - * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
17   - *
18   - * Version: 2.1.1
19   - *
20   - * See file CREDITS for list of people who contributed to this
21   - * project.
22   - *
23   - * This program is free software; you can redistribute it and/or
24   - * modify it under the terms of the GNU General Public License as
25   - * published by the Free Software Foundation, version 2 of the
26   - * License.
27   - *
28   - * This program is distributed in the hope that it will be useful,
29   - * but WITHOUT ANY WARRANTY; without even the implied warranty of
30   - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31   - * GNU General Public License for more details.
32   - *
33   - * You should have received a copy of the GNU General Public License
34   - * along with this program; if not, write to the Free Software
35   - * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
36   - * MA 02111-1307 USA
37   - */
38   -
39   -#include <common.h>
40   -#include <fdtdec.h>
41   -#include <i2c.h>
42   -#include <linux/types.h>
43   -
44   -#include "compatibility.h"
45   -#include "tpm.h"
46   -
47   -DECLARE_GLOBAL_DATA_PTR;
48   -
49   -/* max. buffer size supported by our tpm */
50   -#ifdef TPM_BUFSIZE
51   -#undef TPM_BUFSIZE
52   -#endif
53   -#define TPM_BUFSIZE 1260
54   -/* Address of the TPM on the I2C bus */
55   -#define TPM_I2C_ADDR 0x20
56   -/* max. number of iterations after i2c NAK */
57   -#define MAX_COUNT 3
58   -
59   -#define SLEEP_DURATION 60 /*in usec*/
60   -
61   -/* max. number of iterations after i2c NAK for 'long' commands
62   - * we need this especially for sending TPM_READY, since the cleanup after the
63   - * transtion to the ready state may take some time, but it is unpredictable
64   - * how long it will take.
65   - */
66   -#define MAX_COUNT_LONG 50
67   -
68   -#define SLEEP_DURATION_LONG 210 /* in usec */
69   -
70   -/* expected value for DIDVID register */
71   -#define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L
72   -#define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
73   -
74   -enum i2c_chip_type {
75   - SLB9635,
76   - SLB9645,
77   - UNKNOWN,
78   -};
79   -
80   -static const char * const chip_name[] = {
81   - [SLB9635] = "slb9635tt",
82   - [SLB9645] = "slb9645tt",
83   - [UNKNOWN] = "unknown/fallback to slb9635",
84   -};
85   -
86   -/* Structure to store I2C TPM specific stuff */
87   -struct tpm_inf_dev {
88   - uint addr;
89   - u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */
90   - enum i2c_chip_type chip_type;
91   -};
92   -
93   -static struct tpm_inf_dev tpm_dev = {
94   - .addr = TPM_I2C_ADDR
95   -};
96   -
97   -/*
98   - * iic_tpm_read() - read from TPM register
99   - * @addr: register address to read from
100   - * @buffer: provided by caller
101   - * @len: number of bytes to read
102   - *
103   - * Read len bytes from TPM register and put them into
104   - * buffer (little-endian format, i.e. first byte is put into buffer[0]).
105   - *
106   - * NOTE: TPM is big-endian for multi-byte values. Multi-byte
107   - * values have to be swapped.
108   - *
109   - * Return -EIO on error, 0 on success.
110   - */
111   -int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
112   -{
113   - int rc;
114   - int count;
115   - uint myaddr = addr;
116   - /* we have to use uint here, uchar hangs the board */
117   -
118   - if ((tpm_dev.chip_type == SLB9635) || (tpm_dev.chip_type == UNKNOWN)) {
119   - /* slb9635 protocol should work in both cases */
120   - for (count = 0; count < MAX_COUNT; count++) {
121   - rc = i2c_write(tpm_dev.addr, 0, 0,
122   - (uchar *)&myaddr, 1);
123   - if (rc == 0)
124   - break; /* success, break to skip sleep */
125   -
126   - udelay(SLEEP_DURATION);
127   - }
128   -
129   - if (rc)
130   - return -rc;
131   -
132   - /* After the TPM has successfully received the register address
133   - * it needs some time, thus we're sleeping here again, before
134   - * retrieving the data
135   - */
136   - for (count = 0; count < MAX_COUNT; count++) {
137   - udelay(SLEEP_DURATION);
138   - rc = i2c_read(tpm_dev.addr, 0, 0, buffer, len);
139   - if (rc == 0)
140   - break; /* success, break to skip sleep */
141   - }
142   - } else {
143   - /* use a combined read for newer chips
144   - * unfortunately the smbus functions are not suitable due to
145   - * the 32 byte limit of the smbus.
146   - * retries should usually not be needed, but are kept just to
147   - * be safe on the safe side.
148   - */
149   - for (count = 0; count < MAX_COUNT; count++) {
150   - rc = i2c_read(tpm_dev.addr, addr, 1, buffer, len);
151   - if (rc == 0)
152   - break; /* break here to skip sleep */
153   - udelay(SLEEP_DURATION);
154   - }
155   - }
156   -
157   - /* take care of 'guard time' */
158   - udelay(SLEEP_DURATION);
159   - if (rc)
160   - return -rc;
161   -
162   - return 0;
163   -}
164   -
165   -static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
166   - unsigned int sleep_time,
167   - u8 max_count)
168   -{
169   - int rc = 0;
170   - int count;
171   -
172   - /* prepare send buffer */
173   - tpm_dev.buf[0] = addr;
174   - memcpy(&(tpm_dev.buf[1]), buffer, len);
175   -
176   - for (count = 0; count < max_count; count++) {
177   - rc = i2c_write(tpm_dev.addr, 0, 0, tpm_dev.buf, len + 1);
178   - if (rc == 0)
179   - break; /* success, break to skip sleep */
180   -
181   - udelay(sleep_time);
182   - }
183   -
184   - /* take care of 'guard time' */
185   - udelay(SLEEP_DURATION);
186   - if (rc)
187   - return -rc;
188   -
189   - return 0;
190   -}
191   -
192   -/*
193   - * iic_tpm_write() - write to TPM register
194   - * @addr: register address to write to
195   - * @buffer: containing data to be written
196   - * @len: number of bytes to write
197   - *
198   - * Write len bytes from provided buffer to TPM register (little
199   - * endian format, i.e. buffer[0] is written as first byte).
200   - *
201   - * NOTE: TPM is big-endian for multi-byte values. Multi-byte
202   - * values have to be swapped.
203   - *
204   - * NOTE: use this function instead of the iic_tpm_write_generic function.
205   - *
206   - * Return -EIO on error, 0 on success
207   - */
208   -static int iic_tpm_write(u8 addr, u8 *buffer, size_t len)
209   -{
210   - return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION,
211   - MAX_COUNT);
212   -}
213   -
214   -/*
215   - * This function is needed especially for the cleanup situation after
216   - * sending TPM_READY
217   - * */
218   -static int iic_tpm_write_long(u8 addr, u8 *buffer, size_t len)
219   -{
220   - return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG,
221   - MAX_COUNT_LONG);
222   -}
223   -
224   -#define TPM_HEADER_SIZE 10
225   -
226   -enum tis_access {
227   - TPM_ACCESS_VALID = 0x80,
228   - TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
229   - TPM_ACCESS_REQUEST_PENDING = 0x04,
230   - TPM_ACCESS_REQUEST_USE = 0x02,
231   -};
232   -
233   -enum tis_status {
234   - TPM_STS_VALID = 0x80,
235   - TPM_STS_COMMAND_READY = 0x40,
236   - TPM_STS_GO = 0x20,
237   - TPM_STS_DATA_AVAIL = 0x10,
238   - TPM_STS_DATA_EXPECT = 0x08,
239   -};
240   -
241   -enum tis_defaults {
242   - TIS_SHORT_TIMEOUT = 750, /* ms */
243   - TIS_LONG_TIMEOUT = 2000, /* 2 sec */
244   -};
245   -
246   -#define TPM_ACCESS(l) (0x0000 | ((l) << 4))
247   -#define TPM_STS(l) (0x0001 | ((l) << 4))
248   -#define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4))
249   -#define TPM_DID_VID(l) (0x0006 | ((l) << 4))
250   -
251   -static int check_locality(struct tpm_chip *chip, int loc)
252   -{
253   - u8 buf;
254   - int rc;
255   -
256   - rc = iic_tpm_read(TPM_ACCESS(loc), &buf, 1);
257   - if (rc < 0)
258   - return rc;
259   -
260   - if ((buf & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
261   - (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
262   - chip->vendor.locality = loc;
263   - return loc;
264   - }
265   -
266   - return -1;
267   -}
268   -
269   -static void release_locality(struct tpm_chip *chip, int loc, int force)
270   -{
271   - u8 buf;
272   - if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
273   - return;
274   -
275   - if (force || (buf & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
276   - (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) {
277   - buf = TPM_ACCESS_ACTIVE_LOCALITY;
278   - iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
279   - }
280   -}
281   -
282   -static int request_locality(struct tpm_chip *chip, int loc)
283   -{
284   - unsigned long start, stop;
285   - u8 buf = TPM_ACCESS_REQUEST_USE;
286   -
287   - if (check_locality(chip, loc) >= 0)
288   - return loc; /* we already have the locality */
289   -
290   - iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
291   -
292   - /* wait for burstcount */
293   - start = get_timer(0);
294   - stop = chip->vendor.timeout_a;
295   - do {
296   - if (check_locality(chip, loc) >= 0)
297   - return loc;
298   - msleep(TPM_TIMEOUT);
299   - } while (get_timer(start) < stop);
300   -
301   - return -1;
302   -}
303   -
304   -static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
305   -{
306   - /* NOTE: since i2c read may fail, return 0 in this case --> time-out */
307   - u8 buf;
308   - if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0)
309   - return 0;
310   - else
311   - return buf;
312   -}
313   -
314   -static void tpm_tis_i2c_ready(struct tpm_chip *chip)
315   -{
316   - /* this causes the current command to be aborted */
317   - u8 buf = TPM_STS_COMMAND_READY;
318   - iic_tpm_write_long(TPM_STS(chip->vendor.locality), &buf, 1);
319   -}
320   -
321   -static ssize_t get_burstcount(struct tpm_chip *chip)
322   -{
323   - unsigned long start, stop;
324   - ssize_t burstcnt;
325   - u8 buf[3];
326   -
327   - /* wait for burstcount */
328   - /* which timeout value, spec has 2 answers (c & d) */
329   - start = get_timer(0);
330   - stop = chip->vendor.timeout_d;
331   - do {
332   - /* Note: STS is little endian */
333   - if (iic_tpm_read(TPM_STS(chip->vendor.locality) + 1, buf, 3)
334   - < 0)
335   - burstcnt = 0;
336   - else
337   - burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
338   -
339   - if (burstcnt)
340   - return burstcnt;
341   - msleep(TPM_TIMEOUT);
342   - } while (get_timer(start) < stop);
343   -
344   - return -EBUSY;
345   -}
346   -
347   -static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
348   - int *status)
349   -{
350   - unsigned long start, stop;
351   -
352   - /* check current status */
353   - *status = tpm_tis_i2c_status(chip);
354   - if ((*status & mask) == mask)
355   - return 0;
356   -
357   - start = get_timer(0);
358   - stop = timeout;
359   - do {
360   - msleep(TPM_TIMEOUT);
361   - *status = tpm_tis_i2c_status(chip);
362   - if ((*status & mask) == mask)
363   - return 0;
364   -
365   - } while (get_timer(start) < stop);
366   -
367   - return -ETIME;
368   -}
369   -
370   -static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
371   -{
372   - size_t size = 0;
373   - ssize_t burstcnt;
374   - int rc;
375   -
376   - while (size < count) {
377   - burstcnt = get_burstcount(chip);
378   -
379   - /* burstcount < 0 = tpm is busy */
380   - if (burstcnt < 0)
381   - return burstcnt;
382   -
383   - /* limit received data to max. left */
384   - if (burstcnt > (count - size))
385   - burstcnt = count - size;
386   -
387   - rc = iic_tpm_read(TPM_DATA_FIFO(chip->vendor.locality),
388   - &(buf[size]),
389   - burstcnt);
390   - if (rc == 0)
391   - size += burstcnt;
392   - }
393   -
394   - return size;
395   -}
396   -
397   -static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
398   -{
399   - int size = 0;
400   - int expected, status;
401   -
402   - if (count < TPM_HEADER_SIZE) {
403   - size = -EIO;
404   - goto out;
405   - }
406   -
407   - /* read first 10 bytes, including tag, paramsize, and result */
408   - size = recv_data(chip, buf, TPM_HEADER_SIZE);
409   - if (size < TPM_HEADER_SIZE) {
410   - dev_err(chip->dev, "Unable to read header\n");
411   - goto out;
412   - }
413   -
414   - expected = get_unaligned_be32(buf + TPM_RSP_SIZE_BYTE);
415   - if ((size_t)expected > count) {
416   - size = -EIO;
417   - goto out;
418   - }
419   -
420   - size += recv_data(chip, &buf[TPM_HEADER_SIZE],
421   - expected - TPM_HEADER_SIZE);
422   - if (size < expected) {
423   - dev_err(chip->dev, "Unable to read remainder of result\n");
424   - size = -ETIME;
425   - goto out;
426   - }
427   -
428   - wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
429   - if (status & TPM_STS_DATA_AVAIL) { /* retry? */
430   - dev_err(chip->dev, "Error left over data\n");
431   - size = -EIO;
432   - goto out;
433   - }
434   -
435   -out:
436   - tpm_tis_i2c_ready(chip);
437   - /* The TPM needs some time to clean up here,
438   - * so we sleep rather than keeping the bus busy
439   - */
440   - udelay(2000);
441   - release_locality(chip, chip->vendor.locality, 0);
442   -
443   - return size;
444   -}
445   -
446   -static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
447   -{
448   - int rc, status;
449   - ssize_t burstcnt;
450   - size_t count = 0;
451   - u8 sts = TPM_STS_GO;
452   -
453   - if (len > TPM_BUFSIZE)
454   - return -E2BIG; /* command is too long for our tpm, sorry */
455   -
456   - if (request_locality(chip, 0) < 0)
457   - return -EBUSY;
458   -
459   - status = tpm_tis_i2c_status(chip);
460   - if ((status & TPM_STS_COMMAND_READY) == 0) {
461   - tpm_tis_i2c_ready(chip);
462   - if (wait_for_stat
463   - (chip, TPM_STS_COMMAND_READY,
464   - chip->vendor.timeout_b, &status) < 0) {
465   - rc = -ETIME;
466   - goto out_err;
467   - }
468   - }
469   -
470   - while (count < len - 1) {
471   - burstcnt = get_burstcount(chip);
472   -
473   - /* burstcount < 0 = tpm is busy */
474   - if (burstcnt < 0)
475   - return burstcnt;
476   -
477   - if (burstcnt > (len-1-count))
478   - burstcnt = len-1-count;
479   -
480   -#ifdef CONFIG_TPM_I2C_BURST_LIMITATION
481   - if (burstcnt > CONFIG_TPM_I2C_BURST_LIMITATION)
482   - burstcnt = CONFIG_TPM_I2C_BURST_LIMITATION;
483   -#endif /* CONFIG_TPM_I2C_BURST_LIMITATION */
484   -
485   - rc = iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality),
486   - &(buf[count]), burstcnt);
487   - if (rc == 0)
488   - count += burstcnt;
489   -
490   - wait_for_stat(chip, TPM_STS_VALID,
491   - chip->vendor.timeout_c, &status);
492   -
493   - if ((status & TPM_STS_DATA_EXPECT) == 0) {
494   - rc = -EIO;
495   - goto out_err;
496   - }
497   - }
498   -
499   - /* write last byte */
500   - iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality), &(buf[count]), 1);
501   - wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
502   - if ((status & TPM_STS_DATA_EXPECT) != 0) {
503   - rc = -EIO;
504   - goto out_err;
505   - }
506   -
507   - /* go and do it */
508   - iic_tpm_write(TPM_STS(chip->vendor.locality), &sts, 1);
509   -
510   - return len;
511   -out_err:
512   - tpm_tis_i2c_ready(chip);
513   - /* The TPM needs some time to clean up here,
514   - * so we sleep rather than keeping the bus busy
515   - */
516   - udelay(2000);
517   - release_locality(chip, chip->vendor.locality, 0);
518   -
519   - return rc;
520   -}
521   -
522   -static struct tpm_vendor_specific tpm_tis_i2c = {
523   - .status = tpm_tis_i2c_status,
524   - .recv = tpm_tis_i2c_recv,
525   - .send = tpm_tis_i2c_send,
526   - .cancel = tpm_tis_i2c_ready,
527   - .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
528   - .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
529   - .req_canceled = TPM_STS_COMMAND_READY,
530   -};
531   -
532   -static enum i2c_chip_type tpm_vendor_chip_type(void)
533   -{
534   -#ifdef CONFIG_OF_CONTROL
535   - const void *blob = gd->fdt_blob;
536   -
537   - if (fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9645_TPM) >= 0)
538   - return SLB9645;
539   -
540   - if (fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM) >= 0)
541   - return SLB9635;
542   -#endif
543   - return UNKNOWN;
544   -}
545   -
546   -/* initialisation of i2c tpm */
547   -
548   -
549   -int tpm_vendor_init(uint32_t dev_addr)
550   -{
551   - u32 vendor;
552   - u32 expected_did_vid;
553   - uint old_addr;
554   - int rc = 0;
555   - struct tpm_chip *chip;
556   -
557   - old_addr = tpm_dev.addr;
558   - if (dev_addr != 0)
559   - tpm_dev.addr = dev_addr;
560   -
561   - tpm_dev.chip_type = tpm_vendor_chip_type();
562   -
563   - chip = tpm_register_hardware(&tpm_tis_i2c);
564   - if (chip < 0) {
565   - rc = -ENODEV;
566   - goto out_err;
567   - }
568   -
569   - /* Disable interrupts (not supported) */
570   - chip->vendor.irq = 0;
571   -
572   - /* Default timeouts */
573   - chip->vendor.timeout_a = TIS_SHORT_TIMEOUT;
574   - chip->vendor.timeout_b = TIS_LONG_TIMEOUT;
575   - chip->vendor.timeout_c = TIS_SHORT_TIMEOUT;
576   - chip->vendor.timeout_d = TIS_SHORT_TIMEOUT;
577   -
578   - if (request_locality(chip, 0) != 0) {
579   - rc = -ENODEV;
580   - goto out_err;
581   - }
582   -
583   - /* read four bytes from DID_VID register */
584   - if (iic_tpm_read(TPM_DID_VID(0), (uchar *)&vendor, 4) < 0) {
585   - rc = -EIO;
586   - goto out_release;
587   - }
588   -
589   - if (tpm_dev.chip_type == SLB9635) {
590   - vendor = be32_to_cpu(vendor);
591   - expected_did_vid = TPM_TIS_I2C_DID_VID_9635;
592   - } else {
593   - /* device id and byte order has changed for newer i2c tpms */
594   - expected_did_vid = TPM_TIS_I2C_DID_VID_9645;
595   - }
596   -
597   - if (tpm_dev.chip_type != UNKNOWN && vendor != expected_did_vid) {
598   - dev_err(dev, "vendor id did not match! ID was %08x\n", vendor);
599   - rc = -ENODEV;
600   - goto out_release;
601   - }
602   -
603   - dev_info(dev, "1.2 TPM (chip type %s device-id 0x%X)\n",
604   - chip_name[tpm_dev.chip_type], vendor >> 16);
605   -
606   - /*
607   - * A timeout query to TPM can be placed here.
608   - * Standard timeout values are used so far
609   - */
610   -
611   - return 0;
612   -
613   -out_release:
614   - release_locality(chip, 0, 1);
615   -
616   -out_err:
617   - tpm_dev.addr = old_addr;
618   - return rc;
619   -}
620   -
621   -void tpm_vendor_cleanup(struct tpm_chip *chip)
622   -{
623   - release_locality(chip, chip->vendor.locality, 1);
624   -}
  1 +/*
  2 + * Copyright (C) 2011 Infineon Technologies
  3 + *
  4 + * Authors:
  5 + * Peter Huewe <huewe.external@infineon.com>
  6 + *
  7 + * Description:
  8 + * Device driver for TCG/TCPA TPM (trusted platform module).
  9 + * Specifications at www.trustedcomputinggroup.org
  10 + *
  11 + * It is based on the Linux kernel driver tpm.c from Leendert van
  12 + * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
  13 + *
  14 + * Version: 2.1.1
  15 + *
  16 + * See file CREDITS for list of people who contributed to this
  17 + * project.
  18 + *
  19 + * This program is free software; you can redistribute it and/or
  20 + * modify it under the terms of the GNU General Public License as
  21 + * published by the Free Software Foundation, version 2 of the
  22 + * License.
  23 + *
  24 + * This program is distributed in the hope that it will be useful,
  25 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  27 + * GNU General Public License for more details.
  28 + *
  29 + * You should have received a copy of the GNU General Public License
  30 + * along with this program; if not, write to the Free Software
  31 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  32 + * MA 02111-1307 USA
  33 + */
  34 +
  35 +#include <config.h>
  36 +#include <common.h>
  37 +#include <compiler.h>
  38 +#include <fdtdec.h>
  39 +#include <i2c.h>
  40 +#include <tpm.h>
  41 +#include <asm-generic/errno.h>
  42 +#include <linux/types.h>
  43 +#include <linux/unaligned/be_byteshift.h>
  44 +
  45 +#include "tpm_private.h"
  46 +
  47 +DECLARE_GLOBAL_DATA_PTR;
  48 +
  49 +/* TPM configuration */
  50 +struct tpm {
  51 + int i2c_bus;
  52 + int slave_addr;
  53 + char inited;
  54 + int old_bus;
  55 +} tpm;
  56 +
  57 +/* Global structure for tpm chip data */
  58 +static struct tpm_chip g_chip;
  59 +
  60 +enum tpm_duration {
  61 + TPM_SHORT = 0,
  62 + TPM_MEDIUM = 1,
  63 + TPM_LONG = 2,
  64 + TPM_UNDEFINED,
  65 +};
  66 +
  67 +/* Extended error numbers from linux (see errno.h) */
  68 +#define ECANCELED 125 /* Operation Canceled */
  69 +
  70 +/* Timer frequency. Corresponds to msec timer resolution*/
  71 +#define HZ 1000
  72 +
  73 +#define TPM_MAX_ORDINAL 243
  74 +#define TPM_MAX_PROTECTED_ORDINAL 12
  75 +#define TPM_PROTECTED_ORDINAL_MASK 0xFF
  76 +
  77 +#define TPM_CMD_COUNT_BYTE 2
  78 +#define TPM_CMD_ORDINAL_BYTE 6
  79 +
  80 +/*
  81 + * Array with one entry per ordinal defining the maximum amount
  82 + * of time the chip could take to return the result. The ordinal
  83 + * designation of short, medium or long is defined in a table in
  84 + * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
  85 + * values of the SHORT, MEDIUM, and LONG durations are retrieved
  86 + * from the chip during initialization with a call to tpm_get_timeouts.
  87 + */
  88 +static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
  89 + TPM_UNDEFINED, /* 0 */
  90 + TPM_UNDEFINED,
  91 + TPM_UNDEFINED,
  92 + TPM_UNDEFINED,
  93 + TPM_UNDEFINED,
  94 + TPM_UNDEFINED, /* 5 */
  95 + TPM_UNDEFINED,
  96 + TPM_UNDEFINED,
  97 + TPM_UNDEFINED,
  98 + TPM_UNDEFINED,
  99 + TPM_SHORT, /* 10 */
  100 + TPM_SHORT,
  101 +};
  102 +
  103 +static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
  104 + TPM_UNDEFINED, /* 0 */
  105 + TPM_UNDEFINED,
  106 + TPM_UNDEFINED,
  107 + TPM_UNDEFINED,
  108 + TPM_UNDEFINED,
  109 + TPM_UNDEFINED, /* 5 */
  110 + TPM_UNDEFINED,
  111 + TPM_UNDEFINED,
  112 + TPM_UNDEFINED,
  113 + TPM_UNDEFINED,
  114 + TPM_SHORT, /* 10 */
  115 + TPM_SHORT,
  116 + TPM_MEDIUM,
  117 + TPM_LONG,
  118 + TPM_LONG,
  119 + TPM_MEDIUM, /* 15 */
  120 + TPM_SHORT,
  121 + TPM_SHORT,
  122 + TPM_MEDIUM,
  123 + TPM_LONG,
  124 + TPM_SHORT, /* 20 */
  125 + TPM_SHORT,
  126 + TPM_MEDIUM,
  127 + TPM_MEDIUM,
  128 + TPM_MEDIUM,
  129 + TPM_SHORT, /* 25 */
  130 + TPM_SHORT,
  131 + TPM_MEDIUM,
  132 + TPM_SHORT,
  133 + TPM_SHORT,
  134 + TPM_MEDIUM, /* 30 */
  135 + TPM_LONG,
  136 + TPM_MEDIUM,
  137 + TPM_SHORT,
  138 + TPM_SHORT,
  139 + TPM_SHORT, /* 35 */
  140 + TPM_MEDIUM,
  141 + TPM_MEDIUM,
  142 + TPM_UNDEFINED,
  143 + TPM_UNDEFINED,
  144 + TPM_MEDIUM, /* 40 */
  145 + TPM_LONG,
  146 + TPM_MEDIUM,
  147 + TPM_SHORT,
  148 + TPM_SHORT,
  149 + TPM_SHORT, /* 45 */
  150 + TPM_SHORT,
  151 + TPM_SHORT,
  152 + TPM_SHORT,
  153 + TPM_LONG,
  154 + TPM_MEDIUM, /* 50 */
  155 + TPM_MEDIUM,
  156 + TPM_UNDEFINED,
  157 + TPM_UNDEFINED,
  158 + TPM_UNDEFINED,
  159 + TPM_UNDEFINED, /* 55 */
  160 + TPM_UNDEFINED,
  161 + TPM_UNDEFINED,
  162 + TPM_UNDEFINED,
  163 + TPM_UNDEFINED,
  164 + TPM_MEDIUM, /* 60 */
  165 + TPM_MEDIUM,
  166 + TPM_MEDIUM,
  167 + TPM_SHORT,
  168 + TPM_SHORT,
  169 + TPM_MEDIUM, /* 65 */
  170 + TPM_UNDEFINED,
  171 + TPM_UNDEFINED,
  172 + TPM_UNDEFINED,
  173 + TPM_UNDEFINED,
  174 + TPM_SHORT, /* 70 */
  175 + TPM_SHORT,
  176 + TPM_UNDEFINED,
  177 + TPM_UNDEFINED,
  178 + TPM_UNDEFINED,
  179 + TPM_UNDEFINED, /* 75 */
  180 + TPM_UNDEFINED,
  181 + TPM_UNDEFINED,
  182 + TPM_UNDEFINED,
  183 + TPM_UNDEFINED,
  184 + TPM_LONG, /* 80 */
  185 + TPM_UNDEFINED,
  186 + TPM_MEDIUM,
  187 + TPM_LONG,
  188 + TPM_SHORT,
  189 + TPM_UNDEFINED, /* 85 */
  190 + TPM_UNDEFINED,
  191 + TPM_UNDEFINED,
  192 + TPM_UNDEFINED,
  193 + TPM_UNDEFINED,
  194 + TPM_SHORT, /* 90 */
  195 + TPM_SHORT,
  196 + TPM_SHORT,
  197 + TPM_SHORT,
  198 + TPM_SHORT,
  199 + TPM_UNDEFINED, /* 95 */
  200 + TPM_UNDEFINED,
  201 + TPM_UNDEFINED,
  202 + TPM_UNDEFINED,
  203 + TPM_UNDEFINED,
  204 + TPM_MEDIUM, /* 100 */
  205 + TPM_SHORT,
  206 + TPM_SHORT,
  207 + TPM_UNDEFINED,
  208 + TPM_UNDEFINED,
  209 + TPM_UNDEFINED, /* 105 */
  210 + TPM_UNDEFINED,
  211 + TPM_UNDEFINED,
  212 + TPM_UNDEFINED,
  213 + TPM_UNDEFINED,
  214 + TPM_SHORT, /* 110 */
  215 + TPM_SHORT,
  216 + TPM_SHORT,
  217 + TPM_SHORT,
  218 + TPM_SHORT,
  219 + TPM_SHORT, /* 115 */
  220 + TPM_SHORT,
  221 + TPM_SHORT,
  222 + TPM_UNDEFINED,
  223 + TPM_UNDEFINED,
  224 + TPM_LONG, /* 120 */
  225 + TPM_LONG,
  226 + TPM_MEDIUM,
  227 + TPM_UNDEFINED,
  228 + TPM_SHORT,
  229 + TPM_SHORT, /* 125 */
  230 + TPM_SHORT,
  231 + TPM_LONG,
  232 + TPM_SHORT,
  233 + TPM_SHORT,
  234 + TPM_SHORT, /* 130 */
  235 + TPM_MEDIUM,
  236 + TPM_UNDEFINED,
  237 + TPM_SHORT,
  238 + TPM_MEDIUM,
  239 + TPM_UNDEFINED, /* 135 */
  240 + TPM_UNDEFINED,
  241 + TPM_UNDEFINED,
  242 + TPM_UNDEFINED,
  243 + TPM_UNDEFINED,
  244 + TPM_SHORT, /* 140 */
  245 + TPM_SHORT,
  246 + TPM_UNDEFINED,
  247 + TPM_UNDEFINED,
  248 + TPM_UNDEFINED,
  249 + TPM_UNDEFINED, /* 145 */
  250 + TPM_UNDEFINED,
  251 + TPM_UNDEFINED,
  252 + TPM_UNDEFINED,
  253 + TPM_UNDEFINED,
  254 + TPM_SHORT, /* 150 */
  255 + TPM_MEDIUM,
  256 + TPM_MEDIUM,
  257 + TPM_SHORT,
  258 + TPM_SHORT,
  259 + TPM_UNDEFINED, /* 155 */
  260 + TPM_UNDEFINED,
  261 + TPM_UNDEFINED,
  262 + TPM_UNDEFINED,
  263 + TPM_UNDEFINED,
  264 + TPM_SHORT, /* 160 */
  265 + TPM_SHORT,
  266 + TPM_SHORT,
  267 + TPM_SHORT,
  268 + TPM_UNDEFINED,
  269 + TPM_UNDEFINED, /* 165 */
  270 + TPM_UNDEFINED,
  271 + TPM_UNDEFINED,
  272 + TPM_UNDEFINED,
  273 + TPM_UNDEFINED,
  274 + TPM_LONG, /* 170 */
  275 + TPM_UNDEFINED,
  276 + TPM_UNDEFINED,
  277 + TPM_UNDEFINED,
  278 + TPM_UNDEFINED,
  279 + TPM_UNDEFINED, /* 175 */
  280 + TPM_UNDEFINED,
  281 + TPM_UNDEFINED,
  282 + TPM_UNDEFINED,
  283 + TPM_UNDEFINED,
  284 + TPM_MEDIUM, /* 180 */
  285 + TPM_SHORT,
  286 + TPM_MEDIUM,
  287 + TPM_MEDIUM,
  288 + TPM_MEDIUM,
  289 + TPM_MEDIUM, /* 185 */
  290 + TPM_SHORT,
  291 + TPM_UNDEFINED,
  292 + TPM_UNDEFINED,
  293 + TPM_UNDEFINED,
  294 + TPM_UNDEFINED, /* 190 */
  295 + TPM_UNDEFINED,
  296 + TPM_UNDEFINED,
  297 + TPM_UNDEFINED,
  298 + TPM_UNDEFINED,
  299 + TPM_UNDEFINED, /* 195 */
  300 + TPM_UNDEFINED,
  301 + TPM_UNDEFINED,
  302 + TPM_UNDEFINED,
  303 + TPM_UNDEFINED,
  304 + TPM_SHORT, /* 200 */
  305 + TPM_UNDEFINED,
  306 + TPM_UNDEFINED,
  307 + TPM_UNDEFINED,
  308 + TPM_SHORT,
  309 + TPM_SHORT, /* 205 */
  310 + TPM_SHORT,
  311 + TPM_SHORT,
  312 + TPM_SHORT,
  313 + TPM_SHORT,
  314 + TPM_MEDIUM, /* 210 */
  315 + TPM_UNDEFINED,
  316 + TPM_MEDIUM,
  317 + TPM_MEDIUM,
  318 + TPM_MEDIUM,
  319 + TPM_UNDEFINED, /* 215 */
  320 + TPM_MEDIUM,
  321 + TPM_UNDEFINED,
  322 + TPM_UNDEFINED,
  323 + TPM_SHORT,
  324 + TPM_SHORT, /* 220 */
  325 + TPM_SHORT,
  326 + TPM_SHORT,
  327 + TPM_SHORT,
  328 + TPM_SHORT,
  329 + TPM_UNDEFINED, /* 225 */
  330 + TPM_UNDEFINED,
  331 + TPM_UNDEFINED,
  332 + TPM_UNDEFINED,
  333 + TPM_UNDEFINED,
  334 + TPM_SHORT, /* 230 */
  335 + TPM_LONG,
  336 + TPM_MEDIUM,
  337 + TPM_UNDEFINED,
  338 + TPM_UNDEFINED,
  339 + TPM_UNDEFINED, /* 235 */
  340 + TPM_UNDEFINED,
  341 + TPM_UNDEFINED,
  342 + TPM_UNDEFINED,
  343 + TPM_UNDEFINED,
  344 + TPM_SHORT, /* 240 */
  345 + TPM_UNDEFINED,
  346 + TPM_MEDIUM,
  347 +};
  348 +
  349 +/* Returns max number of milliseconds to wait */
  350 +static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
  351 + u32 ordinal)
  352 +{
  353 + int duration_idx = TPM_UNDEFINED;
  354 + int duration = 0;
  355 +
  356 + if (ordinal < TPM_MAX_ORDINAL) {
  357 + duration_idx = tpm_ordinal_duration[ordinal];
  358 + } else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
  359 + TPM_MAX_PROTECTED_ORDINAL) {
  360 + duration_idx = tpm_protected_ordinal_duration[
  361 + ordinal & TPM_PROTECTED_ORDINAL_MASK];
  362 + }
  363 +
  364 + if (duration_idx != TPM_UNDEFINED)
  365 + duration = chip->vendor.duration[duration_idx];
  366 +
  367 + if (duration <= 0)
  368 + return 2 * 60 * HZ; /* Two minutes timeout */
  369 + else
  370 + return duration;
  371 +}
  372 +
  373 +static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
  374 +{
  375 + ssize_t rc;
  376 + u32 count, ordinal;
  377 + unsigned long start, stop;
  378 +
  379 + struct tpm_chip *chip = &g_chip;
  380 +
  381 + /* switch endianess: big->little */
  382 + count = get_unaligned_be32(buf + TPM_CMD_COUNT_BYTE);
  383 + ordinal = get_unaligned_be32(buf + TPM_CMD_ORDINAL_BYTE);
  384 +
  385 + if (count == 0) {
  386 + error("no data\n");
  387 + return -ENODATA;
  388 + }
  389 + if (count > bufsiz) {
  390 + error("invalid count value %x %zx\n", count, bufsiz);
  391 + return -E2BIG;
  392 + }
  393 +
  394 + rc = chip->vendor.send(chip, (u8 *)buf, count);
  395 + if (rc < 0) {
  396 + error("tpm_transmit: tpm_send: error %zd\n", rc);
  397 + goto out;
  398 + }
  399 +
  400 + if (chip->vendor.irq)
  401 + goto out_recv;
  402 +
  403 + start = get_timer(0);
  404 + stop = tpm_calc_ordinal_duration(chip, ordinal);
  405 + do {
  406 + debug("waiting for status...\n");
  407 + u8 status = chip->vendor.status(chip);
  408 + if ((status & chip->vendor.req_complete_mask) ==
  409 + chip->vendor.req_complete_val) {
  410 + debug("...got it;\n");
  411 + goto out_recv;
  412 + }
  413 +
  414 + if ((status == chip->vendor.req_canceled)) {
  415 + error("Operation Canceled\n");
  416 + rc = -ECANCELED;
  417 + goto out;
  418 + }
  419 + udelay(TPM_TIMEOUT * 1000);
  420 + } while (get_timer(start) < stop);
  421 +
  422 + chip->vendor.cancel(chip);
  423 + error("Operation Timed out\n");
  424 + rc = -ETIME;
  425 + goto out;
  426 +
  427 +out_recv:
  428 + debug("out_recv: reading response...\n");
  429 + rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE);
  430 + if (rc < 0)
  431 + error("tpm_transmit: tpm_recv: error %zd\n", rc);
  432 +
  433 +out:
  434 + return rc;
  435 +}
  436 +
  437 +static int tpm_open(uint32_t dev_addr)
  438 +{
  439 + int rc;
  440 + if (g_chip.is_open)
  441 + return -EBUSY;
  442 + rc = tpm_vendor_init(dev_addr);
  443 + if (rc < 0)
  444 + g_chip.is_open = 0;
  445 + return rc;
  446 +}
  447 +
  448 +static void tpm_close(void)
  449 +{
  450 + if (g_chip.is_open) {
  451 + tpm_vendor_cleanup(&g_chip);
  452 + g_chip.is_open = 0;
  453 + }
  454 +}
  455 +
  456 +static int tpm_select(void)
  457 +{
  458 + int ret;
  459 +
  460 + tpm.old_bus = i2c_get_bus_num();
  461 + if (tpm.old_bus != tpm.i2c_bus) {
  462 + ret = i2c_set_bus_num(tpm.i2c_bus);
  463 + if (ret) {
  464 + debug("%s: Fail to set i2c bus %d\n", __func__,
  465 + tpm.i2c_bus);
  466 + return -1;
  467 + }
  468 + }
  469 + return 0;
  470 +}
  471 +
  472 +static int tpm_deselect(void)
  473 +{
  474 + int ret;
  475 +
  476 + if (tpm.old_bus != i2c_get_bus_num()) {
  477 + ret = i2c_set_bus_num(tpm.old_bus);
  478 + if (ret) {
  479 + debug("%s: Fail to restore i2c bus %d\n",
  480 + __func__, tpm.old_bus);
  481 + return -1;
  482 + }
  483 + }
  484 + tpm.old_bus = -1;
  485 + return 0;
  486 +}
  487 +
  488 +/**
  489 + * Decode TPM configuration.
  490 + *
  491 + * @param dev Returns a configuration of TPM device
  492 + * @return 0 if ok, -1 on error
  493 + */
  494 +static int tpm_decode_config(struct tpm *dev)
  495 +{
  496 +#ifdef CONFIG_OF_CONTROL
  497 + const void *blob = gd->fdt_blob;
  498 + int node, parent;
  499 + int i2c_bus;
  500 +
  501 + node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
  502 + if (node < 0) {
  503 + node = fdtdec_next_compatible(blob, 0,
  504 + COMPAT_INFINEON_SLB9645_TPM);
  505 + }
  506 + if (node < 0) {
  507 + debug("%s: Node not found\n", __func__);
  508 + return -1;
  509 + }
  510 + parent = fdt_parent_offset(blob, node);
  511 + if (parent < 0) {
  512 + debug("%s: Cannot find node parent\n", __func__);
  513 + return -1;
  514 + }
  515 + i2c_bus = i2c_get_bus_num_fdt(parent);
  516 + if (i2c_bus < 0)
  517 + return -1;
  518 + dev->i2c_bus = i2c_bus;
  519 + dev->slave_addr = fdtdec_get_addr(blob, node, "reg");
  520 +#else
  521 + dev->i2c_bus = CONFIG_TPM_TIS_I2C_BUS_NUMBER;
  522 + dev->slave_addr = CONFIG_TPM_TIS_I2C_SLAVE_ADDRESS;
  523 +#endif
  524 + return 0;
  525 +}
  526 +
  527 +struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *entry)
  528 +{
  529 + struct tpm_chip *chip;
  530 +
  531 + /* Driver specific per-device data */
  532 + chip = &g_chip;
  533 + memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
  534 + chip->is_open = 1;
  535 +
  536 + return chip;
  537 +}
  538 +
  539 +int tis_init(void)
  540 +{
  541 + if (tpm.inited)
  542 + return 0;
  543 +
  544 + if (tpm_decode_config(&tpm))
  545 + return -1;
  546 +
  547 + if (tpm_select())
  548 + return -1;
  549 +
  550 + /*
  551 + * Probe TPM twice; the first probing might fail because TPM is asleep,
  552 + * and the probing can wake up TPM.
  553 + */
  554 + if (i2c_probe(tpm.slave_addr) && i2c_probe(tpm.slave_addr)) {
  555 + debug("%s: fail to probe i2c addr 0x%x\n", __func__,
  556 + tpm.slave_addr);
  557 + return -1;
  558 + }
  559 +
  560 + tpm_deselect();
  561 +
  562 + tpm.inited = 1;
  563 +
  564 + return 0;
  565 +}
  566 +
  567 +int tis_open(void)
  568 +{
  569 + int rc;
  570 +
  571 + if (!tpm.inited)
  572 + return -1;
  573 +
  574 + if (tpm_select())
  575 + return -1;
  576 +
  577 + rc = tpm_open(tpm.slave_addr);
  578 +
  579 + tpm_deselect();
  580 +
  581 + return rc;
  582 +}
  583 +
  584 +int tis_close(void)
  585 +{
  586 + if (!tpm.inited)
  587 + return -1;
  588 +
  589 + if (tpm_select())
  590 + return -1;
  591 +
  592 + tpm_close();
  593 +
  594 + tpm_deselect();
  595 +
  596 + return 0;
  597 +}
  598 +
  599 +int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
  600 + uint8_t *recvbuf, size_t *rbuf_len)
  601 +{
  602 + int len;
  603 + uint8_t buf[4096];
  604 +
  605 + if (!tpm.inited)
  606 + return -1;
  607 +
  608 + if (sizeof(buf) < sbuf_size)
  609 + return -1;
  610 +
  611 + memcpy(buf, sendbuf, sbuf_size);
  612 +
  613 + if (tpm_select())
  614 + return -1;
  615 +
  616 + len = tpm_transmit(buf, sbuf_size);
  617 +
  618 + tpm_deselect();
  619 +
  620 + if (len < 10) {
  621 + *rbuf_len = 0;
  622 + return -1;
  623 + }
  624 +
  625 + memcpy(recvbuf, buf, len);
  626 + *rbuf_len = len;
  627 +
  628 + return 0;
  629 +}
drivers/tpm/tpm_private.h
  1 +/*
  2 + * Copyright (C) 2011 Infineon Technologies
  3 + *
  4 + * Authors:
  5 + * Peter Huewe <huewe.external@infineon.com>
  6 + *
  7 + * Version: 2.1.1
  8 + *
  9 + * Description:
  10 + * Device driver for TCG/TCPA TPM (trusted platform module).
  11 + * Specifications at www.trustedcomputinggroup.org
  12 + *
  13 + * It is based on the Linux kernel driver tpm.c from Leendert van
  14 + * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
  15 + *
  16 + *
  17 + * See file CREDITS for list of people who contributed to this
  18 + * project.
  19 + *
  20 + * This program is free software; you can redistribute it and/or
  21 + * modify it under the terms of the GNU General Public License as
  22 + * published by the Free Software Foundation, version 2 of the
  23 + * License.
  24 + *
  25 + * This program is distributed in the hope that it will be useful,
  26 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  28 + * GNU General Public License for more details.
  29 + *
  30 + * You should have received a copy of the GNU General Public License
  31 + * along with this program; if not, write to the Free Software
  32 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  33 + * MA 02111-1307 USA
  34 + */
  35 +
  36 +#ifndef _TPM_PRIVATE_H_
  37 +#define _TPM_PRIVATE_H_
  38 +
  39 +#include <linux/compiler.h>
  40 +#include <linux/types.h>
  41 +
  42 +enum tpm_timeout {
  43 + TPM_TIMEOUT = 5, /* msecs */
  44 +};
  45 +
  46 +/* Size of external transmit buffer (used in tpm_transmit)*/
  47 +#define TPM_BUFSIZE 4096
  48 +
  49 +/* Index of Count field in TPM response buffer */
  50 +#define TPM_RSP_SIZE_BYTE 2
  51 +#define TPM_RSP_RC_BYTE 6
  52 +
  53 +struct tpm_chip;
  54 +
  55 +struct tpm_vendor_specific {
  56 + const u8 req_complete_mask;
  57 + const u8 req_complete_val;
  58 + const u8 req_canceled;
  59 + int irq;
  60 + int (*recv) (struct tpm_chip *, u8 *, size_t);
  61 + int (*send) (struct tpm_chip *, u8 *, size_t);
  62 + void (*cancel) (struct tpm_chip *);
  63 + u8(*status) (struct tpm_chip *);
  64 + int locality;
  65 + unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* msec */
  66 + unsigned long duration[3]; /* msec */
  67 +};
  68 +
  69 +struct tpm_chip {
  70 + int is_open;
  71 + struct tpm_vendor_specific vendor;
  72 +};
  73 +
  74 +struct tpm_input_header {
  75 + __be16 tag;
  76 + __be32 length;
  77 + __be32 ordinal;
  78 +} __packed;
  79 +
  80 +struct tpm_output_header {
  81 + __be16 tag;
  82 + __be32 length;
  83 + __be32 return_code;
  84 +} __packed;
  85 +
  86 +struct timeout_t {
  87 + __be32 a;
  88 + __be32 b;
  89 + __be32 c;
  90 + __be32 d;
  91 +} __packed;
  92 +
  93 +struct duration_t {
  94 + __be32 tpm_short;
  95 + __be32 tpm_medium;
  96 + __be32 tpm_long;
  97 +} __packed;
  98 +
  99 +union cap_t {
  100 + struct timeout_t timeout;
  101 + struct duration_t duration;
  102 +};
  103 +
  104 +struct tpm_getcap_params_in {
  105 + __be32 cap;
  106 + __be32 subcap_size;
  107 + __be32 subcap;
  108 +} __packed;
  109 +
  110 +struct tpm_getcap_params_out {
  111 + __be32 cap_size;
  112 + union cap_t cap;
  113 +} __packed;
  114 +
  115 +union tpm_cmd_header {
  116 + struct tpm_input_header in;
  117 + struct tpm_output_header out;
  118 +};
  119 +
  120 +union tpm_cmd_params {
  121 + struct tpm_getcap_params_out getcap_out;
  122 + struct tpm_getcap_params_in getcap_in;
  123 +};
  124 +
  125 +struct tpm_cmd_t {
  126 + union tpm_cmd_header header;
  127 + union tpm_cmd_params params;
  128 +} __packed;
  129 +
  130 +struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *);
  131 +
  132 +int tpm_vendor_init(uint32_t dev_addr);
  133 +
  134 +void tpm_vendor_cleanup(struct tpm_chip *chip);
  135 +
  136 +
  137 +#endif
drivers/tpm/tpm_tis_i2c.c
  1 +/*
  2 + * Copyright (C) 2011 Infineon Technologies
  3 + *
  4 + * Authors:
  5 + * Peter Huewe <huewe.external@infineon.com>
  6 + *
  7 + * Description:
  8 + * Device driver for TCG/TCPA TPM (trusted platform module).
  9 + * Specifications at www.trustedcomputinggroup.org
  10 + *
  11 + * This device driver implements the TPM interface as defined in
  12 + * the TCG TPM Interface Spec version 1.2, revision 1.0 and the
  13 + * Infineon I2C Protocol Stack Specification v0.20.
  14 + *
  15 + * It is based on the Linux kernel driver tpm.c from Leendert van
  16 + * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
  17 + *
  18 + * Version: 2.1.1
  19 + *
  20 + * See file CREDITS for list of people who contributed to this
  21 + * project.
  22 + *
  23 + * This program is free software; you can redistribute it and/or
  24 + * modify it under the terms of the GNU General Public License as
  25 + * published by the Free Software Foundation, version 2 of the
  26 + * License.
  27 + *
  28 + * This program is distributed in the hope that it will be useful,
  29 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  30 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  31 + * GNU General Public License for more details.
  32 + *
  33 + * You should have received a copy of the GNU General Public License
  34 + * along with this program; if not, write to the Free Software
  35 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  36 + * MA 02111-1307 USA
  37 + */
  38 +
  39 +#include <common.h>
  40 +#include <fdtdec.h>
  41 +#include <compiler.h>
  42 +#include <i2c.h>
  43 +#include <tpm.h>
  44 +#include <asm-generic/errno.h>
  45 +#include <linux/types.h>
  46 +#include <linux/unaligned/be_byteshift.h>
  47 +
  48 +#include "tpm_private.h"
  49 +
  50 +DECLARE_GLOBAL_DATA_PTR;
  51 +
  52 +/* Address of the TPM on the I2C bus */
  53 +#define TPM_I2C_ADDR 0x20
  54 +
  55 +/* Max buffer size supported by our tpm */
  56 +#define TPM_DEV_BUFSIZE 1260
  57 +
  58 +/* Max number of iterations after i2c NAK */
  59 +#define MAX_COUNT 3
  60 +
  61 +/*
  62 + * Max number of iterations after i2c NAK for 'long' commands
  63 + *
  64 + * We need this especially for sending TPM_READY, since the cleanup after the
  65 + * transtion to the ready state may take some time, but it is unpredictable
  66 + * how long it will take.
  67 + */
  68 +#define MAX_COUNT_LONG 50
  69 +
  70 +#define SLEEP_DURATION 60 /* in usec */
  71 +#define SLEEP_DURATION_LONG 210 /* in usec */
  72 +
  73 +#define TPM_HEADER_SIZE 10
  74 +
  75 +/*
  76 + * Expected value for DIDVID register
  77 + *
  78 + * The only device the system knows about at this moment is Infineon slb9635.
  79 + */
  80 +#define TPM_TIS_I2C_DID_VID 0x000b15d1L
  81 +
  82 +enum tis_access {
  83 + TPM_ACCESS_VALID = 0x80,
  84 + TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
  85 + TPM_ACCESS_REQUEST_PENDING = 0x04,
  86 + TPM_ACCESS_REQUEST_USE = 0x02,
  87 +};
  88 +
  89 +enum tis_status {
  90 + TPM_STS_VALID = 0x80,
  91 + TPM_STS_COMMAND_READY = 0x40,
  92 + TPM_STS_GO = 0x20,
  93 + TPM_STS_DATA_AVAIL = 0x10,
  94 + TPM_STS_DATA_EXPECT = 0x08,
  95 +};
  96 +
  97 +enum tis_defaults {
  98 + TIS_SHORT_TIMEOUT = 750, /* ms */
  99 + TIS_LONG_TIMEOUT = 2000, /* ms */
  100 +};
  101 +
  102 +/* expected value for DIDVID register */
  103 +#define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L
  104 +#define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
  105 +
  106 +enum i2c_chip_type {
  107 + SLB9635,
  108 + SLB9645,
  109 + UNKNOWN,
  110 +};
  111 +
  112 +static const char * const chip_name[] = {
  113 + [SLB9635] = "slb9635tt",
  114 + [SLB9645] = "slb9645tt",
  115 + [UNKNOWN] = "unknown/fallback to slb9635",
  116 +};
  117 +
  118 +#define TPM_ACCESS(l) (0x0000 | ((l) << 4))
  119 +#define TPM_STS(l) (0x0001 | ((l) << 4))
  120 +#define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4))
  121 +#define TPM_DID_VID(l) (0x0006 | ((l) << 4))
  122 +
  123 +/* Structure to store I2C TPM specific stuff */
  124 +struct tpm_dev {
  125 + uint addr;
  126 + u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)]; /* Max buffer size + addr */
  127 + enum i2c_chip_type chip_type;
  128 +};
  129 +
  130 +static struct tpm_dev tpm_dev = {
  131 + .addr = TPM_I2C_ADDR
  132 +};
  133 +
  134 +static struct tpm_dev tpm_dev;
  135 +
  136 +/*
  137 + * iic_tpm_read() - read from TPM register
  138 + * @addr: register address to read from
  139 + * @buffer: provided by caller
  140 + * @len: number of bytes to read
  141 + *
  142 + * Read len bytes from TPM register and put them into
  143 + * buffer (little-endian format, i.e. first byte is put into buffer[0]).
  144 + *
  145 + * NOTE: TPM is big-endian for multi-byte values. Multi-byte
  146 + * values have to be swapped.
  147 + *
  148 + * Return -EIO on error, 0 on success.
  149 + */
  150 +static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
  151 +{
  152 + int rc;
  153 + int count;
  154 + uint32_t addrbuf = addr;
  155 +
  156 + if ((tpm_dev.chip_type == SLB9635) || (tpm_dev.chip_type == UNKNOWN)) {
  157 + /* slb9635 protocol should work in both cases */
  158 + for (count = 0; count < MAX_COUNT; count++) {
  159 + rc = i2c_write(tpm_dev.addr, 0, 0,
  160 + (uchar *)&addrbuf, 1);
  161 + if (rc == 0)
  162 + break; /* Success, break to skip sleep */
  163 + udelay(SLEEP_DURATION);
  164 + }
  165 + if (rc)
  166 + return -rc;
  167 +
  168 + /* After the TPM has successfully received the register address
  169 + * it needs some time, thus we're sleeping here again, before
  170 + * retrieving the data
  171 + */
  172 + for (count = 0; count < MAX_COUNT; count++) {
  173 + udelay(SLEEP_DURATION);
  174 + rc = i2c_read(tpm_dev.addr, 0, 0, buffer, len);
  175 + if (rc == 0)
  176 + break; /* success, break to skip sleep */
  177 + }
  178 + } else {
  179 + /*
  180 + * Use a combined read for newer chips.
  181 + * Unfortunately the smbus functions are not suitable due to
  182 + * the 32 byte limit of the smbus.
  183 + * Retries should usually not be needed, but are kept just to
  184 + * be safe on the safe side.
  185 + */
  186 + for (count = 0; count < MAX_COUNT; count++) {
  187 + rc = i2c_read(tpm_dev.addr, addr, 1, buffer, len);
  188 + if (rc == 0)
  189 + break; /* break here to skip sleep */
  190 + udelay(SLEEP_DURATION);
  191 + }
  192 + }
  193 +
  194 + /* Take care of 'guard time' */
  195 + udelay(SLEEP_DURATION);
  196 + if (rc)
  197 + return -rc;
  198 +
  199 + return 0;
  200 +}
  201 +
  202 +static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
  203 + unsigned int sleep_time, u8 max_count)
  204 +{
  205 + int rc = 0;
  206 + int count;
  207 +
  208 + /* Prepare send buffer */
  209 + tpm_dev.buf[0] = addr;
  210 + memcpy(&(tpm_dev.buf[1]), buffer, len);
  211 +
  212 + for (count = 0; count < max_count; count++) {
  213 + rc = i2c_write(tpm_dev.addr, 0, 0, tpm_dev.buf, len + 1);
  214 + if (rc == 0)
  215 + break; /* Success, break to skip sleep */
  216 + udelay(sleep_time);
  217 + }
  218 +
  219 + /* take care of 'guard time' */
  220 + udelay(SLEEP_DURATION);
  221 + if (rc)
  222 + return -rc;
  223 +
  224 + return 0;
  225 +}
  226 +
  227 +/*
  228 + * iic_tpm_write() - write to TPM register
  229 + * @addr: register address to write to
  230 + * @buffer: containing data to be written
  231 + * @len: number of bytes to write
  232 + *
  233 + * Write len bytes from provided buffer to TPM register (little
  234 + * endian format, i.e. buffer[0] is written as first byte).
  235 + *
  236 + * NOTE: TPM is big-endian for multi-byte values. Multi-byte
  237 + * values have to be swapped.
  238 + *
  239 + * NOTE: use this function instead of the iic_tpm_write_generic function.
  240 + *
  241 + * Return -EIO on error, 0 on success
  242 + */
  243 +static int iic_tpm_write(u8 addr, u8 *buffer, size_t len)
  244 +{
  245 + return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION,
  246 + MAX_COUNT);
  247 +}
  248 +
  249 +/*
  250 + * This function is needed especially for the cleanup situation after
  251 + * sending TPM_READY
  252 + */
  253 +static int iic_tpm_write_long(u8 addr, u8 *buffer, size_t len)
  254 +{
  255 + return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG,
  256 + MAX_COUNT_LONG);
  257 +}
  258 +
  259 +static int check_locality(struct tpm_chip *chip, int loc)
  260 +{
  261 + const u8 mask = TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID;
  262 + u8 buf;
  263 + int rc;
  264 +
  265 + rc = iic_tpm_read(TPM_ACCESS(loc), &buf, 1);
  266 + if (rc < 0)
  267 + return rc;
  268 +
  269 + if ((buf & mask) == mask) {
  270 + chip->vendor.locality = loc;
  271 + return loc;
  272 + }
  273 +
  274 + return -1;
  275 +}
  276 +
  277 +static void release_locality(struct tpm_chip *chip, int loc, int force)
  278 +{
  279 + const u8 mask = TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID;
  280 + u8 buf;
  281 +
  282 + if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
  283 + return;
  284 +
  285 + if (force || (buf & mask) == mask) {
  286 + buf = TPM_ACCESS_ACTIVE_LOCALITY;
  287 + iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
  288 + }
  289 +}
  290 +
  291 +static int request_locality(struct tpm_chip *chip, int loc)
  292 +{
  293 + unsigned long start, stop;
  294 + u8 buf = TPM_ACCESS_REQUEST_USE;
  295 +
  296 + if (check_locality(chip, loc) >= 0)
  297 + return loc; /* We already have the locality */
  298 +
  299 + iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
  300 +
  301 + /* Wait for burstcount */
  302 + start = get_timer(0);
  303 + stop = chip->vendor.timeout_a;
  304 + do {
  305 + if (check_locality(chip, loc) >= 0)
  306 + return loc;
  307 + udelay(TPM_TIMEOUT * 1000);
  308 + } while (get_timer(start) < stop);
  309 +
  310 + return -1;
  311 +}
  312 +
  313 +static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
  314 +{
  315 + /* NOTE: Since i2c read may fail, return 0 in this case --> time-out */
  316 + u8 buf;
  317 +
  318 + if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0)
  319 + return 0;
  320 + else
  321 + return buf;
  322 +}
  323 +
  324 +static void tpm_tis_i2c_ready(struct tpm_chip *chip)
  325 +{
  326 + /* This causes the current command to be aborted */
  327 + u8 buf = TPM_STS_COMMAND_READY;
  328 +
  329 + iic_tpm_write_long(TPM_STS(chip->vendor.locality), &buf, 1);
  330 +}
  331 +
  332 +static ssize_t get_burstcount(struct tpm_chip *chip)
  333 +{
  334 + unsigned long start, stop;
  335 + ssize_t burstcnt;
  336 + u8 addr, buf[3];
  337 +
  338 + /* Wait for burstcount */
  339 + /* XXX: Which timeout value? Spec has 2 answers (c & d) */
  340 + start = get_timer(0);
  341 + stop = chip->vendor.timeout_d;
  342 + do {
  343 + /* Note: STS is little endian */
  344 + addr = TPM_STS(chip->vendor.locality) + 1;
  345 + if (iic_tpm_read(addr, buf, 3) < 0)
  346 + burstcnt = 0;
  347 + else
  348 + burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
  349 +
  350 + if (burstcnt)
  351 + return burstcnt;
  352 + udelay(TPM_TIMEOUT * 1000);
  353 + } while (get_timer(start) < stop);
  354 +
  355 + return -EBUSY;
  356 +}
  357 +
  358 +static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
  359 + int *status)
  360 +{
  361 + unsigned long start, stop;
  362 +
  363 + /* Check current status */
  364 + *status = tpm_tis_i2c_status(chip);
  365 + if ((*status & mask) == mask)
  366 + return 0;
  367 +
  368 + start = get_timer(0);
  369 + stop = timeout;
  370 + do {
  371 + udelay(TPM_TIMEOUT * 1000);
  372 + *status = tpm_tis_i2c_status(chip);
  373 + if ((*status & mask) == mask)
  374 + return 0;
  375 + } while (get_timer(start) < stop);
  376 +
  377 + return -ETIME;
  378 +}
  379 +
  380 +static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
  381 +{
  382 + size_t size = 0;
  383 + ssize_t burstcnt;
  384 + int rc;
  385 +
  386 + while (size < count) {
  387 + burstcnt = get_burstcount(chip);
  388 +
  389 + /* burstcount < 0 -> tpm is busy */
  390 + if (burstcnt < 0)
  391 + return burstcnt;
  392 +
  393 + /* Limit received data to max left */
  394 + if (burstcnt > (count - size))
  395 + burstcnt = count - size;
  396 +
  397 + rc = iic_tpm_read(TPM_DATA_FIFO(chip->vendor.locality),
  398 + &(buf[size]), burstcnt);
  399 + if (rc == 0)
  400 + size += burstcnt;
  401 + }
  402 +
  403 + return size;
  404 +}
  405 +
  406 +static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
  407 +{
  408 + int size = 0;
  409 + int expected, status;
  410 +
  411 + if (count < TPM_HEADER_SIZE) {
  412 + size = -EIO;
  413 + goto out;
  414 + }
  415 +
  416 + /* Read first 10 bytes, including tag, paramsize, and result */
  417 + size = recv_data(chip, buf, TPM_HEADER_SIZE);
  418 + if (size < TPM_HEADER_SIZE) {
  419 + error("Unable to read header\n");
  420 + goto out;
  421 + }
  422 +
  423 + expected = get_unaligned_be32(buf + TPM_RSP_SIZE_BYTE);
  424 + if ((size_t)expected > count) {
  425 + size = -EIO;
  426 + goto out;
  427 + }
  428 +
  429 + size += recv_data(chip, &buf[TPM_HEADER_SIZE],
  430 + expected - TPM_HEADER_SIZE);
  431 + if (size < expected) {
  432 + error("Unable to read remainder of result\n");
  433 + size = -ETIME;
  434 + goto out;
  435 + }
  436 +
  437 + wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
  438 + if (status & TPM_STS_DATA_AVAIL) { /* Retry? */
  439 + error("Error left over data\n");
  440 + size = -EIO;
  441 + goto out;
  442 + }
  443 +
  444 +out:
  445 + tpm_tis_i2c_ready(chip);
  446 + /*
  447 + * The TPM needs some time to clean up here,
  448 + * so we sleep rather than keeping the bus busy
  449 + */
  450 + udelay(2000);
  451 + release_locality(chip, chip->vendor.locality, 0);
  452 +
  453 + return size;
  454 +}
  455 +
  456 +static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
  457 +{
  458 + int rc, status;
  459 + ssize_t burstcnt;
  460 + size_t count = 0;
  461 + int retry = 0;
  462 + u8 sts = TPM_STS_GO;
  463 +
  464 + if (len > TPM_DEV_BUFSIZE)
  465 + return -E2BIG; /* Command is too long for our tpm, sorry */
  466 +
  467 + if (request_locality(chip, 0) < 0)
  468 + return -EBUSY;
  469 +
  470 + status = tpm_tis_i2c_status(chip);
  471 + if ((status & TPM_STS_COMMAND_READY) == 0) {
  472 + tpm_tis_i2c_ready(chip);
  473 + if (wait_for_stat(chip, TPM_STS_COMMAND_READY,
  474 + chip->vendor.timeout_b, &status) < 0) {
  475 + rc = -ETIME;
  476 + goto out_err;
  477 + }
  478 + }
  479 +
  480 + burstcnt = get_burstcount(chip);
  481 +
  482 + /* burstcount < 0 -> tpm is busy */
  483 + if (burstcnt < 0)
  484 + return burstcnt;
  485 +
  486 + while (count < len - 1) {
  487 + if (burstcnt > len - 1 - count)
  488 + burstcnt = len - 1 - count;
  489 +
  490 +#ifdef CONFIG_TPM_TIS_I2C_BURST_LIMITATION
  491 + if (retry && burstcnt > CONFIG_TPM_TIS_I2C_BURST_LIMITATION)
  492 + burstcnt = CONFIG_TPM_TIS_I2C_BURST_LIMITATION;
  493 +#endif /* CONFIG_TPM_TIS_I2C_BURST_LIMITATION */
  494 +
  495 + rc = iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality),
  496 + &(buf[count]), burstcnt);
  497 + if (rc == 0)
  498 + count += burstcnt;
  499 + else {
  500 + retry++;
  501 + wait_for_stat(chip, TPM_STS_VALID,
  502 + chip->vendor.timeout_c, &status);
  503 +
  504 + if ((status & TPM_STS_DATA_EXPECT) == 0) {
  505 + rc = -EIO;
  506 + goto out_err;
  507 + }
  508 + }
  509 + }
  510 +
  511 + /* Write last byte */
  512 + iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality), &(buf[count]), 1);
  513 + wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
  514 + if ((status & TPM_STS_DATA_EXPECT) != 0) {
  515 + rc = -EIO;
  516 + goto out_err;
  517 + }
  518 +
  519 + /* Go and do it */
  520 + iic_tpm_write(TPM_STS(chip->vendor.locality), &sts, 1);
  521 +
  522 + return len;
  523 +
  524 +out_err:
  525 + tpm_tis_i2c_ready(chip);
  526 + /*
  527 + * The TPM needs some time to clean up here,
  528 + * so we sleep rather than keeping the bus busy
  529 + */
  530 + udelay(2000);
  531 + release_locality(chip, chip->vendor.locality, 0);
  532 +
  533 + return rc;
  534 +}
  535 +
  536 +static struct tpm_vendor_specific tpm_tis_i2c = {
  537 + .status = tpm_tis_i2c_status,
  538 + .recv = tpm_tis_i2c_recv,
  539 + .send = tpm_tis_i2c_send,
  540 + .cancel = tpm_tis_i2c_ready,
  541 + .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
  542 + .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
  543 + .req_canceled = TPM_STS_COMMAND_READY,
  544 +};
  545 +
  546 +
  547 +static enum i2c_chip_type tpm_vendor_chip_type(void)
  548 +{
  549 +#ifdef CONFIG_OF_CONTROL
  550 + const void *blob = gd->fdt_blob;
  551 +
  552 + if (fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9645_TPM) >= 0)
  553 + return SLB9645;
  554 +
  555 + if (fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM) >= 0)
  556 + return SLB9635;
  557 +#endif
  558 + return UNKNOWN;
  559 +}
  560 +
  561 +/* Initialisation of i2c tpm */
  562 +int tpm_vendor_init(uint32_t dev_addr)
  563 +{
  564 + u32 vendor;
  565 + u32 expected_did_vid;
  566 + uint old_addr;
  567 + int rc = 0;
  568 + struct tpm_chip *chip;
  569 +
  570 + old_addr = tpm_dev.addr;
  571 + if (dev_addr != 0)
  572 + tpm_dev.addr = dev_addr;
  573 +
  574 + tpm_dev.chip_type = tpm_vendor_chip_type();
  575 +
  576 + chip = tpm_register_hardware(&tpm_tis_i2c);
  577 + if (chip < 0) {
  578 + rc = -ENODEV;
  579 + goto out_err;
  580 + }
  581 +
  582 + /* Disable interrupts (not supported) */
  583 + chip->vendor.irq = 0;
  584 +
  585 + /* Default timeouts */
  586 + chip->vendor.timeout_a = TIS_SHORT_TIMEOUT;
  587 + chip->vendor.timeout_b = TIS_LONG_TIMEOUT;
  588 + chip->vendor.timeout_c = TIS_SHORT_TIMEOUT;
  589 + chip->vendor.timeout_d = TIS_SHORT_TIMEOUT;
  590 +
  591 + if (request_locality(chip, 0) < 0) {
  592 + rc = -ENODEV;
  593 + goto out_err;
  594 + }
  595 +
  596 + /* Read four bytes from DID_VID register */
  597 + if (iic_tpm_read(TPM_DID_VID(0), (uchar *)&vendor, 4) < 0) {
  598 + rc = -EIO;
  599 + goto out_release;
  600 + }
  601 +
  602 + if (tpm_dev.chip_type == SLB9635) {
  603 + vendor = be32_to_cpu(vendor);
  604 + expected_did_vid = TPM_TIS_I2C_DID_VID_9635;
  605 + } else {
  606 + /* device id and byte order has changed for newer i2c tpms */
  607 + expected_did_vid = TPM_TIS_I2C_DID_VID_9645;
  608 + }
  609 +
  610 + if (tpm_dev.chip_type != UNKNOWN && vendor != expected_did_vid) {
  611 + error("Vendor id did not match! ID was %08x\n", vendor);
  612 + rc = -ENODEV;
  613 + goto out_release;
  614 + }
  615 +
  616 + debug("1.2 TPM (chip type %s device-id 0x%X)\n",
  617 + chip_name[tpm_dev.chip_type], vendor >> 16);
  618 +
  619 + /*
  620 + * A timeout query to TPM can be placed here.
  621 + * Standard timeout values are used so far
  622 + */
  623 +
  624 + return 0;
  625 +
  626 +out_release:
  627 + release_locality(chip, 0, 1);
  628 +
  629 +out_err:
  630 + tpm_dev.addr = old_addr;
  631 + return rc;
  632 +}
  633 +
  634 +void tpm_vendor_cleanup(struct tpm_chip *chip)
  635 +{
  636 + release_locality(chip, chip->vendor.locality, 1);
  637 +}
include/configs/exynos5250-dt.h
... ... @@ -142,9 +142,9 @@
142 142 /* TPM */
143 143 #define CONFIG_TPM
144 144 #define CONFIG_CMD_TPM
145   -#define CONFIG_INFINEON_TPM_I2C
146   -#define CONFIG_INFINEON_TPM_I2C_BUS 3
147   -#define CONFIG_INFINEON_TPM_I2C_ADDR 0x20
  145 +#define CONFIG_TPM_TIS_I2C
  146 +#define CONFIG_TPM_TIS_I2C_BUS_NUMBER 3
  147 +#define CONFIG_TPM_TIS_I2C_SLAVE_ADDR 0x20
148 148  
149 149 /* MMC SPL */
150 150 #define CONFIG_SPL