1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <common.h>
16#include <dm.h>
17#include <fdtdec.h>
18#include <i2c.h>
19#include <log.h>
20#include <tpm-v1.h>
21#include <errno.h>
22#include <linux/delay.h>
23#include <linux/types.h>
24#include <asm/unaligned.h>
25
26#include "tpm_tis.h"
27#include "tpm_internal.h"
28
29#define TPM_ACCESS 0x0
30#define TPM_STS 0x18
31#define TPM_DATA_FIFO 0x24
32
33#define LOCALITY0 0
34
35#define TPM_DUMMY_BYTE 0xAA
36#define TPM_ST33ZP24_I2C_SLAVE_ADDR 0x13
37
38#define TPM_WRITE_DIRECTION 0x80
39
40
41
42
43
44
45
46
47
48static int st33zp24_i2c_write8_reg(struct udevice *dev, u8 tpm_register,
49 const u8 *tpm_data, size_t tpm_size)
50{
51 struct tpm_chip_priv *chip_priv = dev_get_uclass_priv(dev);
52
53 chip_priv->buf[0] = tpm_register;
54 memcpy(chip_priv->buf + 1, tpm_data, tpm_size);
55
56 return dm_i2c_write(dev, 0, chip_priv->buf, tpm_size + 1);
57}
58
59
60
61
62
63
64
65
66
67static int st33zp24_i2c_read8_reg(struct udevice *dev, u8 tpm_register,
68 u8 *tpm_data, size_t tpm_size)
69{
70 int status;
71 u8 data;
72
73 data = TPM_DUMMY_BYTE;
74 status = st33zp24_i2c_write8_reg(dev, tpm_register, &data, 1);
75 if (status < 0)
76 return status;
77
78 return dm_i2c_read(dev, 0, tpm_data, tpm_size);
79}
80
81
82
83
84
85
86
87
88
89
90static int st33zp24_i2c_write(struct udevice *dev, u8 tpm_register,
91 const u8 *tpm_data, size_t tpm_size)
92{
93 return st33zp24_i2c_write8_reg(dev, tpm_register | TPM_WRITE_DIRECTION,
94 tpm_data, tpm_size);
95}
96
97
98
99
100
101
102
103
104
105
106static int st33zp24_i2c_read(struct udevice *dev, u8 tpm_register,
107 u8 *tpm_data, size_t tpm_size)
108{
109 return st33zp24_i2c_read8_reg(dev, tpm_register, tpm_data, tpm_size);
110}
111
112
113
114
115
116static void st33zp24_i2c_release_locality(struct udevice *dev)
117{
118 u8 data = TPM_ACCESS_ACTIVE_LOCALITY;
119
120 st33zp24_i2c_write(dev, TPM_ACCESS, &data, 1);
121}
122
123
124
125
126
127
128static int st33zp24_i2c_check_locality(struct udevice *dev)
129{
130 struct tpm_chip *chip = dev_get_priv(dev);
131 u8 data;
132 u8 status;
133
134 status = st33zp24_i2c_read(dev, TPM_ACCESS, &data, 1);
135 if (!status && (data &
136 (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
137 (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
138 return chip->locality;
139
140 return -EACCES;
141}
142
143
144
145
146
147
148static int st33zp24_i2c_request_locality(struct udevice *dev)
149{
150 struct tpm_chip *chip = dev_get_priv(dev);
151 unsigned long start, stop;
152 long ret;
153 u8 data;
154
155 if (st33zp24_i2c_check_locality(dev) == chip->locality)
156 return chip->locality;
157
158 data = TPM_ACCESS_REQUEST_USE;
159 ret = st33zp24_i2c_write(dev, TPM_ACCESS, &data, 1);
160 if (ret < 0)
161 return ret;
162
163
164 start = get_timer(0);
165 stop = chip->timeout_a;
166 do {
167 if (st33zp24_i2c_check_locality(dev) >= 0)
168 return chip->locality;
169 udelay(TPM_TIMEOUT_MS * 1000);
170 } while (get_timer(start) < stop);
171
172 return -EACCES;
173}
174
175
176
177
178
179
180static u8 st33zp24_i2c_status(struct udevice *dev)
181{
182 u8 data;
183
184 st33zp24_i2c_read(dev, TPM_STS, &data, 1);
185
186 return data;
187}
188
189
190
191
192
193
194static int st33zp24_i2c_get_burstcount(struct udevice *dev)
195{
196 struct tpm_chip *chip = dev_get_priv(dev);
197 unsigned long start, stop;
198 int burstcnt, status;
199 u8 tpm_reg, temp;
200
201
202 start = get_timer(0);
203 stop = chip->timeout_d;
204 do {
205 tpm_reg = TPM_STS + 1;
206 status = st33zp24_i2c_read(dev, tpm_reg, &temp, 1);
207 if (status < 0)
208 return -EBUSY;
209
210 tpm_reg = TPM_STS + 2;
211 burstcnt = temp;
212 status = st33zp24_i2c_read(dev, tpm_reg, &temp, 1);
213 if (status < 0)
214 return -EBUSY;
215
216 burstcnt |= temp << 8;
217 if (burstcnt)
218 return burstcnt;
219 udelay(TIS_SHORT_TIMEOUT_MS * 1000);
220 } while (get_timer(start) < stop);
221
222 return -EBUSY;
223}
224
225
226
227
228
229
230static void st33zp24_i2c_cancel(struct udevice *dev)
231{
232 u8 data;
233
234 data = TPM_STS_COMMAND_READY;
235 st33zp24_i2c_write(dev, TPM_STS, &data, 1);
236}
237
238
239
240
241
242
243
244
245
246static int st33zp24_i2c_wait_for_stat(struct udevice *dev, u8 mask,
247 unsigned long timeout, int *status)
248{
249 unsigned long start, stop;
250
251
252 *status = st33zp24_i2c_status(dev);
253 if ((*status & mask) == mask)
254 return 0;
255
256 start = get_timer(0);
257 stop = timeout;
258 do {
259 udelay(TPM_TIMEOUT_MS * 1000);
260 *status = st33zp24_i2c_status(dev);
261 if ((*status & mask) == mask)
262 return 0;
263 } while (get_timer(start) < stop);
264
265 return -ETIME;
266}
267
268
269
270
271
272
273
274
275static int st33zp24_i2c_recv_data(struct udevice *dev, u8 *buf, size_t count)
276{
277 struct tpm_chip *chip = dev_get_priv(dev);
278 int size = 0, burstcnt, len, ret, status;
279
280 while (size < count &&
281 st33zp24_i2c_wait_for_stat(dev, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
282 chip->timeout_c, &status) == 0) {
283 burstcnt = st33zp24_i2c_get_burstcount(dev);
284 if (burstcnt < 0)
285 return burstcnt;
286 len = min_t(int, burstcnt, count - size);
287 ret = st33zp24_i2c_read(dev, TPM_DATA_FIFO, buf + size, len);
288 if (ret < 0)
289 return ret;
290
291 size += len;
292 }
293
294 return size;
295}
296
297
298
299
300
301
302
303
304static int st33zp24_i2c_recv(struct udevice *dev, u8 *buf, size_t count)
305{
306 struct tpm_chip *chip = dev_get_priv(dev);
307 int size;
308 unsigned int expected;
309
310 if (!chip)
311 return -ENODEV;
312
313 if (count < TPM_HEADER_SIZE) {
314 size = -EIO;
315 goto out;
316 }
317
318 size = st33zp24_i2c_recv_data(dev, buf, TPM_HEADER_SIZE);
319 if (size < TPM_HEADER_SIZE) {
320 debug("TPM error, unable to read header\n");
321 goto out;
322 }
323
324 expected = get_unaligned_be32(buf + 2);
325 if (expected > count || expected < TPM_HEADER_SIZE) {
326 size = -EIO;
327 goto out;
328 }
329
330 size += st33zp24_i2c_recv_data(dev, &buf[TPM_HEADER_SIZE],
331 expected - TPM_HEADER_SIZE);
332 if (size < expected) {
333 debug("TPM error, unable to read remaining bytes of result\n");
334 size = -EIO;
335 goto out;
336 }
337
338out:
339 st33zp24_i2c_cancel(dev);
340 st33zp24_i2c_release_locality(dev);
341
342 return size;
343}
344
345
346
347
348
349
350
351
352static int st33zp24_i2c_send(struct udevice *dev, const u8 *buf, size_t len)
353{
354 struct tpm_chip *chip = dev_get_priv(dev);
355 u32 i, size;
356 int burstcnt, ret, status;
357 u8 data, tpm_stat;
358
359 if (!chip)
360 return -ENODEV;
361 if (len < TPM_HEADER_SIZE)
362 return -EIO;
363
364 ret = st33zp24_i2c_request_locality(dev);
365 if (ret < 0)
366 return ret;
367
368 tpm_stat = st33zp24_i2c_status(dev);
369 if ((tpm_stat & TPM_STS_COMMAND_READY) == 0) {
370 st33zp24_i2c_cancel(dev);
371 if (st33zp24_i2c_wait_for_stat(dev, TPM_STS_COMMAND_READY,
372 chip->timeout_b, &status) < 0) {
373 ret = -ETIME;
374 goto out_err;
375 }
376 }
377
378 for (i = 0; i < len - 1;) {
379 burstcnt = st33zp24_i2c_get_burstcount(dev);
380 if (burstcnt < 0)
381 return burstcnt;
382
383 size = min_t(int, len - i - 1, burstcnt);
384 ret = st33zp24_i2c_write(dev, TPM_DATA_FIFO, buf + i, size);
385 if (ret < 0)
386 goto out_err;
387
388 i += size;
389 }
390
391 tpm_stat = st33zp24_i2c_status(dev);
392 if ((tpm_stat & TPM_STS_DATA_EXPECT) == 0) {
393 ret = -EIO;
394 goto out_err;
395 }
396
397 ret = st33zp24_i2c_write(dev, TPM_DATA_FIFO, buf + len - 1, 1);
398 if (ret < 0)
399 goto out_err;
400
401 tpm_stat = st33zp24_i2c_status(dev);
402 if ((tpm_stat & TPM_STS_DATA_EXPECT) != 0) {
403 ret = -EIO;
404 goto out_err;
405 }
406
407 data = TPM_STS_GO;
408 ret = st33zp24_i2c_write(dev, TPM_STS, &data, 1);
409 if (ret < 0)
410 goto out_err;
411
412 return len;
413
414out_err:
415 st33zp24_i2c_cancel(dev);
416 st33zp24_i2c_release_locality(dev);
417
418 return ret;
419}
420
421static int st33zp24_i2c_cleanup(struct udevice *dev)
422{
423 st33zp24_i2c_cancel(dev);
424
425
426
427
428 mdelay(2);
429 st33zp24_i2c_release_locality(dev);
430
431 return 0;
432}
433
434static int st33zp24_i2c_init(struct udevice *dev)
435{
436 struct tpm_chip *chip = dev_get_priv(dev);
437
438 chip->is_open = 1;
439
440
441 chip->timeout_a = TIS_SHORT_TIMEOUT_MS;
442 chip->timeout_b = TIS_LONG_TIMEOUT_MS;
443 chip->timeout_c = TIS_SHORT_TIMEOUT_MS;
444 chip->timeout_d = TIS_SHORT_TIMEOUT_MS;
445
446 chip->locality = LOCALITY0;
447
448
449
450
451
452
453 return 0;
454}
455
456static int st33zp24_i2c_open(struct udevice *dev)
457{
458 struct tpm_chip *chip = dev_get_priv(dev);
459 int rc;
460
461 debug("%s: start\n", __func__);
462 if (chip->is_open)
463 return -EBUSY;
464
465 rc = st33zp24_i2c_init(dev);
466 if (rc < 0)
467 chip->is_open = 0;
468
469 return rc;
470}
471
472static int st33zp24_i2c_close(struct udevice *dev)
473{
474 struct tpm_chip *chip = dev_get_priv(dev);
475
476 if (chip->is_open) {
477 st33zp24_i2c_release_locality(dev);
478 chip->is_open = 0;
479 chip->vend_dev = 0;
480 }
481
482 return 0;
483}
484
485static int st33zp24_i2c_get_desc(struct udevice *dev, char *buf, int size)
486{
487 struct tpm_chip *chip = dev_get_priv(dev);
488
489 if (size < 50)
490 return -ENOSPC;
491
492 return snprintf(buf, size, "1.2 TPM (%s, chip type %s device-id 0x%x)",
493 chip->is_open ? "open" : "closed",
494 dev->name,
495 chip->vend_dev >> 16);
496}
497
498static const struct tpm_ops st33zp24_i2c_tpm_ops = {
499 .open = st33zp24_i2c_open,
500 .close = st33zp24_i2c_close,
501 .recv = st33zp24_i2c_recv,
502 .send = st33zp24_i2c_send,
503 .cleanup = st33zp24_i2c_cleanup,
504 .get_desc = st33zp24_i2c_get_desc,
505};
506
507static int st33zp24_i2c_probe(struct udevice *dev)
508{
509 struct tpm_chip *chip = dev_get_priv(dev);
510
511
512 chip->timeout_a = TIS_SHORT_TIMEOUT_MS;
513 chip->timeout_b = TIS_LONG_TIMEOUT_MS;
514 chip->timeout_c = TIS_SHORT_TIMEOUT_MS;
515 chip->timeout_d = TIS_SHORT_TIMEOUT_MS;
516
517 chip->locality = LOCALITY0;
518
519 i2c_set_chip_offset_len(dev, 0);
520
521 debug("ST33ZP24 I2C TPM from STMicroelectronics found\n");
522
523 return 0;
524}
525
526static int st33zp24_i2c_remove(struct udevice *dev)
527{
528 st33zp24_i2c_release_locality(dev);
529
530 return 0;
531}
532
533static const struct udevice_id st33zp24_i2c_ids[] = {
534 { .compatible = "st,st33zp24-i2c" },
535 { }
536};
537
538U_BOOT_DRIVER(st33zp24_i2c) = {
539 .name = "st33zp24-i2c",
540 .id = UCLASS_TPM,
541 .of_match = of_match_ptr(st33zp24_i2c_ids),
542 .probe = st33zp24_i2c_probe,
543 .remove = st33zp24_i2c_remove,
544 .ops = &st33zp24_i2c_tpm_ops,
545 .priv_auto = sizeof(struct tpm_chip),
546};
547