]>
Commit | Line | Data |
---|---|---|
b75fdc11 CR |
1 | /* |
2 | * STMicroelectronics TPM ST33ZP24 SPI UBOOT driver | |
3 | * | |
4 | * Copyright (C) 2016 STMicroelectronics | |
5 | * | |
6 | * Description: Device driver for ST33ZP24 SPI TPM TCG. | |
7 | * | |
8 | * This device driver implements the TPM interface as defined in | |
9 | * the TCG TPM Interface Spec version 1.21, revision 1.0 and the | |
10 | * STMicroelectronics Protocol Stack Specification version 1.2.0. | |
11 | * | |
12 | * SPDX-License-Identifier: GPL-2.0+ | |
13 | */ | |
14 | ||
15 | #include <common.h> | |
16 | #include <dm.h> | |
17 | #include <fdtdec.h> | |
18 | #include <spi.h> | |
19 | #include <tpm.h> | |
20 | #include <errno.h> | |
21 | #include <linux/types.h> | |
22 | #include <asm/unaligned.h> | |
23 | #include <linux/compat.h> | |
24 | ||
25 | #include "tpm_tis.h" | |
26 | #include "tpm_internal.h" | |
27 | ||
28 | #define TPM_ACCESS 0x0 | |
29 | #define TPM_STS 0x18 | |
30 | #define TPM_DATA_FIFO 0x24 | |
31 | ||
32 | #define LOCALITY0 0 | |
33 | ||
34 | #define TPM_DATA_FIFO 0x24 | |
35 | #define TPM_INTF_CAPABILITY 0x14 | |
36 | ||
37 | #define TPM_DUMMY_BYTE 0x00 | |
38 | #define TPM_WRITE_DIRECTION 0x80 | |
39 | ||
40 | #define MAX_SPI_LATENCY 15 | |
41 | #define LOCALITY0 0 | |
42 | ||
43 | #define ST33ZP24_OK 0x5A | |
44 | #define ST33ZP24_UNDEFINED_ERR 0x80 | |
45 | #define ST33ZP24_BADLOCALITY 0x81 | |
46 | #define ST33ZP24_TISREGISTER_UKNOWN 0x82 | |
47 | #define ST33ZP24_LOCALITY_NOT_ACTIVATED 0x83 | |
48 | #define ST33ZP24_HASH_END_BEFORE_HASH_START 0x84 | |
49 | #define ST33ZP24_BAD_COMMAND_ORDER 0x85 | |
50 | #define ST33ZP24_INCORECT_RECEIVED_LENGTH 0x86 | |
51 | #define ST33ZP24_TPM_FIFO_OVERFLOW 0x89 | |
52 | #define ST33ZP24_UNEXPECTED_READ_FIFO 0x8A | |
53 | #define ST33ZP24_UNEXPECTED_WRITE_FIFO 0x8B | |
54 | #define ST33ZP24_CMDRDY_SET_WHEN_PROCESSING_HASH_END 0x90 | |
55 | #define ST33ZP24_DUMMY_BYTES 0x00 | |
56 | ||
57 | /* | |
58 | * TPM command can be up to 2048 byte, A TPM response can be up to | |
59 | * 1024 byte. | |
60 | * Between command and response, there are latency byte (up to 15 | |
61 | * usually on st33zp24 2 are enough). | |
62 | * | |
63 | * Overall when sending a command and expecting an answer we need if | |
64 | * worst case: | |
65 | * 2048 (for the TPM command) + 1024 (for the TPM answer). We need | |
66 | * some latency byte before the answer is available (max 15). | |
67 | * We have 2048 + 1024 + 15. | |
68 | */ | |
69 | #define ST33ZP24_SPI_BUFFER_SIZE (TPM_BUFSIZE + (TPM_BUFSIZE / 2) +\ | |
70 | MAX_SPI_LATENCY) | |
71 | ||
72 | struct st33zp24_spi_phy { | |
73 | int latency; | |
74 | ||
75 | u8 tx_buf[ST33ZP24_SPI_BUFFER_SIZE]; | |
76 | u8 rx_buf[ST33ZP24_SPI_BUFFER_SIZE]; | |
77 | }; | |
78 | ||
79 | static int st33zp24_spi_status_to_errno(u8 code) | |
80 | { | |
81 | switch (code) { | |
82 | case ST33ZP24_OK: | |
83 | return 0; | |
84 | case ST33ZP24_UNDEFINED_ERR: | |
85 | case ST33ZP24_BADLOCALITY: | |
86 | case ST33ZP24_TISREGISTER_UKNOWN: | |
87 | case ST33ZP24_LOCALITY_NOT_ACTIVATED: | |
88 | case ST33ZP24_HASH_END_BEFORE_HASH_START: | |
89 | case ST33ZP24_BAD_COMMAND_ORDER: | |
90 | case ST33ZP24_UNEXPECTED_READ_FIFO: | |
91 | case ST33ZP24_UNEXPECTED_WRITE_FIFO: | |
92 | case ST33ZP24_CMDRDY_SET_WHEN_PROCESSING_HASH_END: | |
93 | return -EPROTO; | |
94 | case ST33ZP24_INCORECT_RECEIVED_LENGTH: | |
95 | case ST33ZP24_TPM_FIFO_OVERFLOW: | |
96 | return -EMSGSIZE; | |
97 | case ST33ZP24_DUMMY_BYTES: | |
98 | return -ENOSYS; | |
99 | } | |
100 | return code; | |
101 | } | |
102 | ||
103 | /* | |
104 | * st33zp24_spi_send | |
105 | * Send byte to TPM register according to the ST33ZP24 SPI protocol. | |
106 | * @param: tpm, the chip description | |
107 | * @param: tpm_register, the tpm tis register where the data should be written | |
108 | * @param: tpm_data, the tpm_data to write inside the tpm_register | |
109 | * @param: tpm_size, The length of the data | |
110 | * @return: should be zero if success else a negative error code. | |
111 | */ | |
112 | static int st33zp24_spi_write(struct udevice *dev, u8 tpm_register, | |
113 | const u8 *tpm_data, size_t tpm_size) | |
114 | { | |
115 | int total_length = 0, ret; | |
116 | struct spi_slave *slave = dev_get_parent_priv(dev); | |
117 | struct st33zp24_spi_phy *phy = dev_get_platdata(dev); | |
118 | ||
119 | u8 *tx_buf = (u8 *)phy->tx_buf; | |
120 | u8 *rx_buf = phy->rx_buf; | |
121 | ||
122 | tx_buf[total_length++] = TPM_WRITE_DIRECTION | LOCALITY0; | |
123 | tx_buf[total_length++] = tpm_register; | |
124 | ||
125 | if (tpm_size > 0 && tpm_register == TPM_DATA_FIFO) { | |
126 | tx_buf[total_length++] = tpm_size >> 8; | |
127 | tx_buf[total_length++] = tpm_size; | |
128 | } | |
129 | memcpy(tx_buf + total_length, tpm_data, tpm_size); | |
130 | total_length += tpm_size; | |
131 | ||
132 | memset(tx_buf + total_length, TPM_DUMMY_BYTE, phy->latency); | |
133 | ||
134 | total_length += phy->latency; | |
135 | ||
136 | ret = spi_claim_bus(slave); | |
137 | if (ret < 0) | |
138 | return ret; | |
139 | ||
140 | ret = spi_xfer(slave, total_length * 8, tx_buf, rx_buf, | |
141 | SPI_XFER_BEGIN | SPI_XFER_END); | |
142 | if (ret < 0) | |
143 | return ret; | |
144 | ||
145 | spi_release_bus(slave); | |
146 | ||
147 | if (ret == 0) | |
148 | ret = rx_buf[total_length - 1]; | |
149 | ||
150 | return st33zp24_spi_status_to_errno(ret); | |
151 | } | |
152 | ||
153 | /* | |
154 | * spi_st33zp24_spi_read8_reg | |
155 | * Recv byte from the TIS register according to the ST33ZP24 SPI protocol. | |
156 | * @param: tpm, the chip description | |
157 | * @param: tpm_loc, the locality to read register from | |
158 | * @param: tpm_register, the tpm tis register where the data should be read | |
159 | * @param: tpm_data, the TPM response | |
160 | * @param: tpm_size, tpm TPM response size to read. | |
161 | * @return: should be zero if success else a negative error code. | |
162 | */ | |
163 | static u8 st33zp24_spi_read8_reg(struct udevice *dev, u8 tpm_register, | |
164 | u8 *tpm_data, size_t tpm_size) | |
165 | { | |
166 | int total_length = 0, ret; | |
167 | struct spi_slave *slave = dev_get_parent_priv(dev); | |
168 | struct st33zp24_spi_phy *phy = dev_get_platdata(dev); | |
169 | ||
170 | u8 *tx_buf = (u8 *)phy->tx_buf; | |
171 | u8 *rx_buf = phy->rx_buf; | |
172 | ||
173 | /* Pre-Header */ | |
174 | tx_buf[total_length++] = LOCALITY0; | |
175 | tx_buf[total_length++] = tpm_register; | |
176 | ||
177 | memset(&tx_buf[total_length], TPM_DUMMY_BYTE, | |
178 | phy->latency + tpm_size); | |
179 | total_length += phy->latency + tpm_size; | |
180 | ||
181 | ret = spi_claim_bus(slave); | |
182 | if (ret < 0) | |
183 | return 0; | |
184 | ||
185 | ret = spi_xfer(slave, total_length * 8, tx_buf, rx_buf, | |
186 | SPI_XFER_BEGIN | SPI_XFER_END); | |
187 | if (ret < 0) | |
188 | return 0; | |
189 | ||
190 | spi_release_bus(slave); | |
191 | ||
192 | if (tpm_size > 0 && ret == 0) { | |
193 | ret = rx_buf[total_length - tpm_size - 1]; | |
194 | memcpy(tpm_data, rx_buf + total_length - tpm_size, tpm_size); | |
195 | } | |
196 | return ret; | |
197 | } | |
198 | ||
199 | /* | |
200 | * st33zp24_spi_recv | |
201 | * Recv byte from the TIS register according to the ST33ZP24 SPI protocol. | |
202 | * @param: phy_id, the phy description | |
203 | * @param: tpm_register, the tpm tis register where the data should be read | |
204 | * @param: tpm_data, the TPM response | |
205 | * @param: tpm_size, tpm TPM response size to read. | |
206 | * @return: number of byte read successfully: should be one if success. | |
207 | */ | |
208 | static int st33zp24_spi_read(struct udevice *dev, u8 tpm_register, | |
209 | u8 *tpm_data, size_t tpm_size) | |
210 | { | |
211 | int ret; | |
212 | ||
213 | ret = st33zp24_spi_read8_reg(dev, tpm_register, tpm_data, tpm_size); | |
214 | if (!st33zp24_spi_status_to_errno(ret)) | |
215 | return tpm_size; | |
216 | ||
217 | return ret; | |
218 | } | |
219 | ||
220 | static int st33zp24_spi_evaluate_latency(struct udevice *dev) | |
221 | { | |
222 | int latency = 1, status = 0; | |
223 | u8 data = 0; | |
224 | struct st33zp24_spi_phy *phy = dev_get_platdata(dev); | |
225 | ||
226 | while (!status && latency < MAX_SPI_LATENCY) { | |
227 | phy->latency = latency; | |
228 | status = st33zp24_spi_read8_reg(dev, TPM_INTF_CAPABILITY, | |
229 | &data, 1); | |
230 | latency++; | |
231 | } | |
232 | if (status < 0) | |
233 | return status; | |
234 | if (latency == MAX_SPI_LATENCY) | |
235 | return -ENODEV; | |
236 | ||
237 | return latency - 1; | |
238 | } | |
239 | ||
240 | /* | |
241 | * st33zp24_spi_release_locality release the active locality | |
242 | * @param: chip, the tpm chip description. | |
243 | */ | |
244 | static void st33zp24_spi_release_locality(struct udevice *dev) | |
245 | { | |
246 | u8 data = TPM_ACCESS_ACTIVE_LOCALITY; | |
247 | ||
248 | st33zp24_spi_write(dev, TPM_ACCESS, &data, 1); | |
249 | } | |
250 | ||
251 | /* | |
252 | * st33zp24_spi_check_locality if the locality is active | |
253 | * @param: chip, the tpm chip description | |
254 | * @return: the active locality or -EACCES. | |
255 | */ | |
256 | static int st33zp24_spi_check_locality(struct udevice *dev) | |
257 | { | |
258 | u8 data; | |
259 | u8 status; | |
260 | struct tpm_chip *chip = dev_get_priv(dev); | |
261 | ||
262 | status = st33zp24_spi_read(dev, TPM_ACCESS, &data, 1); | |
263 | if (status && (data & | |
264 | (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) == | |
265 | (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) | |
266 | return chip->locality; | |
267 | ||
268 | return -EACCES; | |
269 | } | |
270 | ||
271 | /* | |
272 | * st33zp24_spi_request_locality request the TPM locality | |
273 | * @param: chip, the chip description | |
274 | * @return: the active locality or negative value. | |
275 | */ | |
276 | static int st33zp24_spi_request_locality(struct udevice *dev) | |
277 | { | |
278 | unsigned long start, stop; | |
279 | long ret; | |
280 | u8 data; | |
281 | struct tpm_chip *chip = dev_get_priv(dev); | |
282 | ||
283 | if (st33zp24_spi_check_locality(dev) == chip->locality) | |
284 | return chip->locality; | |
285 | ||
286 | data = TPM_ACCESS_REQUEST_USE; | |
287 | ret = st33zp24_spi_write(dev, TPM_ACCESS, &data, 1); | |
288 | if (ret < 0) | |
289 | return ret; | |
290 | ||
291 | /* wait for locality activated */ | |
292 | start = get_timer(0); | |
293 | stop = chip->timeout_a; | |
294 | do { | |
295 | if (st33zp24_spi_check_locality(dev) >= 0) | |
296 | return chip->locality; | |
297 | udelay(TPM_TIMEOUT_MS * 1000); | |
298 | } while (get_timer(start) < stop); | |
299 | ||
300 | return -EACCES; | |
301 | } | |
302 | ||
303 | /* | |
304 | * st33zp24_spi_status return the TPM_STS register | |
305 | * @param: chip, the tpm chip description | |
306 | * @return: the TPM_STS register value. | |
307 | */ | |
308 | static u8 st33zp24_spi_status(struct udevice *dev) | |
309 | { | |
310 | u8 data; | |
311 | ||
312 | st33zp24_spi_read(dev, TPM_STS, &data, 1); | |
313 | return data; | |
314 | } | |
315 | ||
316 | /* | |
317 | * st33zp24_spi_get_burstcount return the burstcount address 0x19 0x1A | |
318 | * @param: chip, the chip description | |
319 | * return: the burstcount or -TPM_DRIVER_ERR in case of error. | |
320 | */ | |
321 | static int st33zp24_spi_get_burstcount(struct udevice *dev) | |
322 | { | |
323 | struct tpm_chip *chip = dev_get_priv(dev); | |
324 | unsigned long start, stop; | |
325 | int burstcnt, status; | |
326 | u8 tpm_reg, temp; | |
327 | ||
328 | /* wait for burstcount */ | |
329 | start = get_timer(0); | |
330 | stop = chip->timeout_d; | |
331 | do { | |
332 | tpm_reg = TPM_STS + 1; | |
333 | status = st33zp24_spi_read(dev, tpm_reg, &temp, 1); | |
334 | if (status < 0) | |
335 | return -EBUSY; | |
336 | ||
337 | tpm_reg = TPM_STS + 2; | |
338 | burstcnt = temp; | |
339 | status = st33zp24_spi_read(dev, tpm_reg, &temp, 1); | |
340 | if (status < 0) | |
341 | return -EBUSY; | |
342 | ||
343 | burstcnt |= temp << 8; | |
344 | if (burstcnt) | |
345 | return burstcnt; | |
346 | udelay(TIS_SHORT_TIMEOUT_MS * 1000); | |
347 | } while (get_timer(start) < stop); | |
348 | ||
349 | return -EBUSY; | |
350 | } | |
351 | ||
352 | /* | |
353 | * st33zp24_spi_cancel, cancel the current command execution or | |
354 | * set STS to COMMAND READY. | |
355 | * @param: chip, tpm_chip description. | |
356 | */ | |
357 | static void st33zp24_spi_cancel(struct udevice *dev) | |
358 | { | |
359 | u8 data; | |
360 | ||
361 | data = TPM_STS_COMMAND_READY; | |
362 | st33zp24_spi_write(dev, TPM_STS, &data, 1); | |
363 | } | |
364 | ||
365 | /* | |
366 | * st33zp24_spi_wait_for_stat wait for a TPM_STS value | |
367 | * @param: chip, the tpm chip description | |
368 | * @param: mask, the value mask to wait | |
369 | * @param: timeout, the timeout | |
370 | * @param: status, | |
371 | * @return: the tpm status, 0 if success, -ETIME if timeout is reached. | |
372 | */ | |
373 | static int st33zp24_spi_wait_for_stat(struct udevice *dev, u8 mask, | |
374 | unsigned long timeout, int *status) | |
375 | { | |
376 | unsigned long start, stop; | |
377 | ||
378 | /* Check current status */ | |
379 | *status = st33zp24_spi_status(dev); | |
380 | if ((*status & mask) == mask) | |
381 | return 0; | |
382 | ||
383 | start = get_timer(0); | |
384 | stop = timeout; | |
385 | do { | |
386 | udelay(TPM_TIMEOUT_MS * 1000); | |
387 | *status = st33zp24_spi_status(dev); | |
388 | if ((*status & mask) == mask) | |
389 | return 0; | |
390 | } while (get_timer(start) < stop); | |
391 | ||
392 | return -ETIME; | |
393 | } | |
394 | ||
395 | /* | |
396 | * st33zp24_spi_recv_data receive data | |
397 | * @param: chip, the tpm chip description | |
398 | * @param: buf, the buffer where the data are received | |
399 | * @param: count, the number of data to receive | |
400 | * @return: the number of bytes read from TPM FIFO. | |
401 | */ | |
402 | static int st33zp24_spi_recv_data(struct udevice *dev, u8 *buf, size_t count) | |
403 | { | |
404 | struct tpm_chip *chip = dev_get_priv(dev); | |
405 | int size = 0, burstcnt, len, ret, status; | |
406 | ||
407 | while (size < count && | |
408 | st33zp24_spi_wait_for_stat(dev, TPM_STS_DATA_AVAIL | TPM_STS_VALID, | |
409 | chip->timeout_c, &status) == 0) { | |
410 | burstcnt = st33zp24_spi_get_burstcount(dev); | |
411 | if (burstcnt < 0) | |
412 | return burstcnt; | |
413 | len = min_t(int, burstcnt, count - size); | |
414 | ret = st33zp24_spi_read(dev, TPM_DATA_FIFO, buf + size, len); | |
415 | if (ret < 0) | |
416 | return ret; | |
417 | ||
418 | size += len; | |
419 | } | |
420 | return size; | |
421 | } | |
422 | ||
423 | /* | |
424 | * st33zp24_spi_recv received TPM response through TPM phy. | |
425 | * @param: chip, tpm_chip description. | |
426 | * @param: buf, the buffer to store data. | |
427 | * @param: count, the number of bytes that can received (sizeof buf). | |
428 | * @return: Returns zero in case of success else -EIO. | |
429 | */ | |
430 | static int st33zp24_spi_recv(struct udevice *dev, u8 *buf, size_t count) | |
431 | { | |
432 | struct tpm_chip *chip = dev_get_priv(dev); | |
433 | int size, expected; | |
434 | ||
435 | if (!chip) | |
436 | return -ENODEV; | |
437 | ||
438 | if (count < TPM_HEADER_SIZE) { | |
439 | size = -EIO; | |
440 | goto out; | |
441 | } | |
442 | ||
443 | size = st33zp24_spi_recv_data(dev, buf, TPM_HEADER_SIZE); | |
444 | if (size < TPM_HEADER_SIZE) { | |
445 | debug("TPM error, unable to read header\n"); | |
446 | goto out; | |
447 | } | |
448 | ||
449 | expected = get_unaligned_be32(buf + 2); | |
450 | if (expected > count) { | |
451 | size = -EIO; | |
452 | goto out; | |
453 | } | |
454 | ||
455 | size += st33zp24_spi_recv_data(dev, &buf[TPM_HEADER_SIZE], | |
456 | expected - TPM_HEADER_SIZE); | |
457 | if (size < expected) { | |
458 | debug("TPM error, unable to read remaining bytes of result\n"); | |
459 | size = -EIO; | |
460 | goto out; | |
461 | } | |
462 | ||
463 | out: | |
464 | st33zp24_spi_cancel(dev); | |
465 | st33zp24_spi_release_locality(dev); | |
466 | ||
467 | return size; | |
468 | } | |
469 | ||
470 | /* | |
471 | * st33zp24_spi_send send TPM commands through TPM phy. | |
472 | * @param: chip, tpm_chip description. | |
473 | * @param: buf, the buffer to send. | |
474 | * @param: len, the number of bytes to send. | |
475 | * @return: Returns zero in case of success else the negative error code. | |
476 | */ | |
477 | static int st33zp24_spi_send(struct udevice *dev, const u8 *buf, size_t len) | |
478 | { | |
479 | struct tpm_chip *chip = dev_get_priv(dev); | |
480 | u32 i, size; | |
481 | int burstcnt, ret, status; | |
482 | u8 data, tpm_stat; | |
483 | ||
484 | if (!chip) | |
485 | return -ENODEV; | |
486 | if (len < TPM_HEADER_SIZE) | |
487 | return -EIO; | |
488 | ||
489 | ret = st33zp24_spi_request_locality(dev); | |
490 | if (ret < 0) | |
491 | return ret; | |
492 | ||
493 | tpm_stat = st33zp24_spi_status(dev); | |
494 | if ((tpm_stat & TPM_STS_COMMAND_READY) == 0) { | |
495 | st33zp24_spi_cancel(dev); | |
496 | if (st33zp24_spi_wait_for_stat(dev, TPM_STS_COMMAND_READY, | |
497 | chip->timeout_b, &status) < 0) { | |
498 | ret = -ETIME; | |
499 | goto out_err; | |
500 | } | |
501 | } | |
502 | ||
503 | for (i = 0; i < len - 1;) { | |
504 | burstcnt = st33zp24_spi_get_burstcount(dev); | |
505 | if (burstcnt < 0) | |
506 | return burstcnt; | |
507 | ||
508 | size = min_t(int, len - i - 1, burstcnt); | |
509 | ret = st33zp24_spi_write(dev, TPM_DATA_FIFO, buf + i, size); | |
510 | if (ret < 0) | |
511 | goto out_err; | |
512 | ||
513 | i += size; | |
514 | } | |
515 | ||
516 | tpm_stat = st33zp24_spi_status(dev); | |
517 | if ((tpm_stat & TPM_STS_DATA_EXPECT) == 0) { | |
518 | ret = -EIO; | |
519 | goto out_err; | |
520 | } | |
521 | ||
522 | ret = st33zp24_spi_write(dev, TPM_DATA_FIFO, buf + len - 1, 1); | |
523 | if (ret < 0) | |
524 | goto out_err; | |
525 | ||
526 | tpm_stat = st33zp24_spi_status(dev); | |
527 | if ((tpm_stat & TPM_STS_DATA_EXPECT) != 0) { | |
528 | ret = -EIO; | |
529 | goto out_err; | |
530 | } | |
531 | ||
532 | data = TPM_STS_GO; | |
533 | ret = st33zp24_spi_write(dev, TPM_STS, &data, 1); | |
534 | if (ret < 0) | |
535 | goto out_err; | |
536 | ||
537 | return len; | |
538 | ||
539 | out_err: | |
540 | st33zp24_spi_cancel(dev); | |
541 | st33zp24_spi_release_locality(dev); | |
542 | ||
543 | return ret; | |
544 | } | |
545 | ||
546 | static int st33zp24_spi_cleanup(struct udevice *dev) | |
547 | { | |
548 | st33zp24_spi_cancel(dev); | |
549 | /* | |
550 | * The TPM needs some time to clean up here, | |
551 | * so we sleep rather than keeping the bus busy | |
552 | */ | |
553 | mdelay(2); | |
554 | st33zp24_spi_release_locality(dev); | |
555 | ||
556 | return 0; | |
557 | } | |
558 | ||
559 | static int st33zp24_spi_init(struct udevice *dev) | |
560 | { | |
561 | struct tpm_chip *chip = dev_get_priv(dev); | |
562 | struct st33zp24_spi_phy *phy = dev_get_platdata(dev); | |
563 | ||
564 | chip->is_open = 1; | |
565 | ||
566 | /* Default timeouts - these could move to the device tree */ | |
567 | chip->timeout_a = TIS_SHORT_TIMEOUT_MS; | |
568 | chip->timeout_b = TIS_LONG_TIMEOUT_MS; | |
569 | chip->timeout_c = TIS_SHORT_TIMEOUT_MS; | |
570 | chip->timeout_d = TIS_SHORT_TIMEOUT_MS; | |
571 | ||
572 | chip->locality = LOCALITY0; | |
573 | ||
574 | phy->latency = st33zp24_spi_evaluate_latency(dev); | |
575 | if (phy->latency <= 0) | |
576 | return -ENODEV; | |
577 | ||
578 | /* | |
579 | * A timeout query to TPM can be placed here. | |
580 | * Standard timeout values are used so far | |
581 | */ | |
582 | ||
583 | return 0; | |
584 | } | |
585 | ||
586 | static int st33zp24_spi_open(struct udevice *dev) | |
587 | { | |
588 | struct tpm_chip *chip = dev_get_priv(dev); | |
589 | int rc; | |
590 | ||
591 | debug("%s: start\n", __func__); | |
592 | if (chip->is_open) | |
593 | return -EBUSY; | |
594 | ||
595 | rc = st33zp24_spi_init(dev); | |
596 | if (rc < 0) | |
597 | chip->is_open = 0; | |
598 | ||
599 | return rc; | |
600 | } | |
601 | ||
602 | static int st33zp24_spi_close(struct udevice *dev) | |
603 | { | |
604 | struct tpm_chip *chip = dev_get_priv(dev); | |
605 | ||
606 | if (chip->is_open) { | |
607 | st33zp24_spi_release_locality(dev); | |
608 | chip->is_open = 0; | |
609 | chip->vend_dev = 0; | |
610 | } | |
611 | ||
612 | return 0; | |
613 | } | |
614 | ||
615 | static int st33zp24_spi_get_desc(struct udevice *dev, char *buf, int size) | |
616 | { | |
617 | struct tpm_chip *chip = dev_get_priv(dev); | |
618 | ||
619 | if (size < 50) | |
620 | return -ENOSPC; | |
621 | ||
622 | return snprintf(buf, size, "1.2 TPM (%s, chip type %s device-id 0x%x)", | |
623 | chip->is_open ? "open" : "closed", | |
624 | dev->name, | |
625 | chip->vend_dev >> 16); | |
626 | } | |
627 | ||
628 | const struct tpm_ops st33zp24_spi_tpm_ops = { | |
629 | .open = st33zp24_spi_open, | |
630 | .close = st33zp24_spi_close, | |
631 | .recv = st33zp24_spi_recv, | |
632 | .send = st33zp24_spi_send, | |
633 | .cleanup = st33zp24_spi_cleanup, | |
634 | .get_desc = st33zp24_spi_get_desc, | |
635 | }; | |
636 | ||
637 | static int st33zp24_spi_probe(struct udevice *dev) | |
638 | { | |
639 | struct tpm_chip_priv *uc_priv = dev_get_uclass_priv(dev); | |
640 | ||
641 | uc_priv->duration_ms[TPM_SHORT] = TIS_SHORT_TIMEOUT_MS; | |
642 | uc_priv->duration_ms[TPM_MEDIUM] = TIS_LONG_TIMEOUT_MS; | |
643 | uc_priv->duration_ms[TPM_LONG] = TIS_LONG_TIMEOUT_MS; | |
644 | uc_priv->retry_time_ms = TPM_TIMEOUT_MS; | |
645 | ||
646 | debug("ST33ZP24 SPI TPM from STMicroelectronics found\n"); | |
647 | ||
648 | return 0; | |
649 | } | |
650 | ||
651 | static int st33zp24_spi_remove(struct udevice *dev) | |
652 | { | |
653 | st33zp24_spi_release_locality(dev); | |
654 | ||
655 | return 0; | |
656 | } | |
657 | ||
658 | static const struct udevice_id st33zp24_spi_ids[] = { | |
659 | { .compatible = "st,st33zp24-spi" }, | |
660 | { } | |
661 | }; | |
662 | ||
663 | U_BOOT_DRIVER(st33zp24_spi_spi) = { | |
664 | .name = "st33zp24-spi", | |
665 | .id = UCLASS_TPM, | |
666 | .of_match = of_match_ptr(st33zp24_spi_ids), | |
667 | .probe = st33zp24_spi_probe, | |
668 | .remove = st33zp24_spi_remove, | |
669 | .ops = &st33zp24_spi_tpm_ops, | |
670 | .priv_auto_alloc_size = sizeof(struct tpm_chip), | |
671 | .platdata_auto_alloc_size = sizeof(struct st33zp24_spi_phy), | |
672 | }; |