]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/tpm/tpm_tis_lpc.c
dm: tpm: Convert LPC driver to driver model
[karo-tx-uboot.git] / drivers / tpm / tpm_tis_lpc.c
1 /*
2  * Copyright (c) 2011 The Chromium OS Authors.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 /*
8  * The code in this file is based on the article "Writing a TPM Device Driver"
9  * published on http://ptgmedia.pearsoncmg.com.
10  *
11  * One principal difference is that in the simplest config the other than 0
12  * TPM localities do not get mapped by some devices (for instance, by Infineon
13  * slb9635), so this driver provides access to locality 0 only.
14  */
15
16 #include <common.h>
17 #include <dm.h>
18 #include <mapmem.h>
19 #include <tis.h>
20 #include <tpm.h>
21 #include <asm/io.h>
22
23 #define PREFIX "lpc_tpm: "
24
25 struct tpm_locality {
26         u32 access;
27         u8 padding0[4];
28         u32 int_enable;
29         u8 vector;
30         u8 padding1[3];
31         u32 int_status;
32         u32 int_capability;
33         u32 tpm_status;
34         u8 padding2[8];
35         u8 data;
36         u8 padding3[3803];
37         u32 did_vid;
38         u8 rid;
39         u8 padding4[251];
40 };
41
42 struct tpm_tis_lpc_priv {
43         struct tpm_locality *regs;
44 };
45
46 /*
47  * This pointer refers to the TPM chip, 5 of its localities are mapped as an
48  * array.
49  */
50 #define TPM_TOTAL_LOCALITIES    5
51
52 /* Some registers' bit field definitions */
53 #define TIS_STS_VALID                  (1 << 7) /* 0x80 */
54 #define TIS_STS_COMMAND_READY          (1 << 6) /* 0x40 */
55 #define TIS_STS_TPM_GO                 (1 << 5) /* 0x20 */
56 #define TIS_STS_DATA_AVAILABLE         (1 << 4) /* 0x10 */
57 #define TIS_STS_EXPECT                 (1 << 3) /* 0x08 */
58 #define TIS_STS_RESPONSE_RETRY         (1 << 1) /* 0x02 */
59
60 #define TIS_ACCESS_TPM_REG_VALID_STS   (1 << 7) /* 0x80 */
61 #define TIS_ACCESS_ACTIVE_LOCALITY     (1 << 5) /* 0x20 */
62 #define TIS_ACCESS_BEEN_SEIZED         (1 << 4) /* 0x10 */
63 #define TIS_ACCESS_SEIZE               (1 << 3) /* 0x08 */
64 #define TIS_ACCESS_PENDING_REQUEST     (1 << 2) /* 0x04 */
65 #define TIS_ACCESS_REQUEST_USE         (1 << 1) /* 0x02 */
66 #define TIS_ACCESS_TPM_ESTABLISHMENT   (1 << 0) /* 0x01 */
67
68 #define TIS_STS_BURST_COUNT_MASK       (0xffff)
69 #define TIS_STS_BURST_COUNT_SHIFT      (8)
70
71  /* 1 second is plenty for anything TPM does. */
72 #define MAX_DELAY_US    (1000 * 1000)
73
74 /* Retrieve burst count value out of the status register contents. */
75 static u16 burst_count(u32 status)
76 {
77         return (status >> TIS_STS_BURST_COUNT_SHIFT) &
78                         TIS_STS_BURST_COUNT_MASK;
79 }
80
81 /* TPM access wrappers to support tracing */
82 static u8 tpm_read_byte(struct tpm_tis_lpc_priv *priv, const u8 *ptr)
83 {
84         u8  ret = readb(ptr);
85         debug(PREFIX "Read reg 0x%4.4x returns 0x%2.2x\n",
86               (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, ret);
87         return ret;
88 }
89
90 static u32 tpm_read_word(struct tpm_tis_lpc_priv *priv, const u32 *ptr)
91 {
92         u32  ret = readl(ptr);
93         debug(PREFIX "Read reg 0x%4.4x returns 0x%8.8x\n",
94               (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, ret);
95         return ret;
96 }
97
98 static void tpm_write_byte(struct tpm_tis_lpc_priv *priv, u8 value, u8 *ptr)
99 {
100         debug(PREFIX "Write reg 0x%4.4x with 0x%2.2x\n",
101               (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, value);
102         writeb(value, ptr);
103 }
104
105 static void tpm_write_word(struct tpm_tis_lpc_priv *priv, u32 value,
106                            u32 *ptr)
107 {
108         debug(PREFIX "Write reg 0x%4.4x with 0x%8.8x\n",
109               (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, value);
110         writel(value, ptr);
111 }
112
113 /*
114  * tis_wait_reg()
115  *
116  * Wait for at least a second for a register to change its state to match the
117  * expected state. Normally the transition happens within microseconds.
118  *
119  * @reg - pointer to the TPM register
120  * @mask - bitmask for the bitfield(s) to watch
121  * @expected - value the field(s) are supposed to be set to
122  *
123  * Returns the register contents in case the expected value was found in the
124  * appropriate register bits, or -ETIMEDOUT on timeout.
125  */
126 static int tis_wait_reg(struct tpm_tis_lpc_priv *priv, u32 *reg, u8 mask,
127                         u8 expected)
128 {
129         u32 time_us = MAX_DELAY_US;
130
131         while (time_us > 0) {
132                 u32 value = tpm_read_word(priv, reg);
133                 if ((value & mask) == expected)
134                         return value;
135                 udelay(1); /* 1 us */
136                 time_us--;
137         }
138
139         return -ETIMEDOUT;
140 }
141
142 /*
143  * Probe the TPM device and try determining its manufacturer/device name.
144  *
145  * Returns 0 on success, -ve on error
146  */
147 static int tpm_tis_lpc_probe(struct udevice *dev)
148 {
149         struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
150         u32 vid, did;
151         fdt_addr_t addr;
152         u32 didvid;
153
154         addr = dev_get_addr(dev);
155         if (addr == FDT_ADDR_T_NONE)
156                 return -EINVAL;
157         priv->regs = map_sysmem(addr, 0);
158         didvid = tpm_read_word(priv, &priv->regs[0].did_vid);
159
160         vid = didvid & 0xffff;
161         did = (didvid >> 16) & 0xffff;
162         if (vid != 0x15d1 || did != 0xb) {
163                 debug("Invalid vendor/device ID %04x/%04x\n", vid, did);
164                 return -ENOSYS;
165         }
166
167         debug("Found TPM %s by %s\n", "SLB9635 TT 1.2", "Infineon");
168
169         return 0;
170 }
171
172 /*
173  * tis_senddata()
174  *
175  * send the passed in data to the TPM device.
176  *
177  * @data - address of the data to send, byte by byte
178  * @len - length of the data to send
179  *
180  * Returns 0 on success, -ve on error (in case the device does not accept
181  * the entire command).
182  */
183 static int tis_senddata(struct udevice *dev, const u8 *data, size_t len)
184 {
185         struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
186         struct tpm_locality *regs = priv->regs;
187         u32 offset = 0;
188         u16 burst = 0;
189         u32 max_cycles = 0;
190         u8 locality = 0;
191         u32 value;
192
193         value = tis_wait_reg(priv, &regs[locality].tpm_status,
194                              TIS_STS_COMMAND_READY, TIS_STS_COMMAND_READY);
195         if (value == -ETIMEDOUT) {
196                 printf("%s:%d - failed to get 'command_ready' status\n",
197                        __FILE__, __LINE__);
198                 return value;
199         }
200         burst = burst_count(value);
201
202         while (1) {
203                 unsigned count;
204
205                 /* Wait till the device is ready to accept more data. */
206                 while (!burst) {
207                         if (max_cycles++ == MAX_DELAY_US) {
208                                 printf("%s:%d failed to feed %d bytes of %d\n",
209                                        __FILE__, __LINE__, len - offset, len);
210                                 return -ETIMEDOUT;
211                         }
212                         udelay(1);
213                         burst = burst_count(tpm_read_word(priv,
214                                         &regs[locality].tpm_status));
215                 }
216
217                 max_cycles = 0;
218
219                 /*
220                  * Calculate number of bytes the TPM is ready to accept in one
221                  * shot.
222                  *
223                  * We want to send the last byte outside of the loop (hence
224                  * the -1 below) to make sure that the 'expected' status bit
225                  * changes to zero exactly after the last byte is fed into the
226                  * FIFO.
227                  */
228                 count = min((u32)burst, len - offset - 1);
229                 while (count--)
230                         tpm_write_byte(priv, data[offset++],
231                                        &regs[locality].data);
232
233                 value = tis_wait_reg(priv, &regs[locality].tpm_status,
234                                      TIS_STS_VALID, TIS_STS_VALID);
235
236                 if ((value == -ETIMEDOUT) || !(value & TIS_STS_EXPECT)) {
237                         printf("%s:%d TPM command feed overflow\n",
238                                __FILE__, __LINE__);
239                         return value == -ETIMEDOUT ? value : -EIO;
240                 }
241
242                 burst = burst_count(value);
243                 if ((offset == (len - 1)) && burst) {
244                         /*
245                          * We need to be able to send the last byte to the
246                          * device, so burst size must be nonzero before we
247                          * break out.
248                          */
249                         break;
250                 }
251         }
252
253         /* Send the last byte. */
254         tpm_write_byte(priv, data[offset++], &regs[locality].data);
255         /*
256          * Verify that TPM does not expect any more data as part of this
257          * command.
258          */
259         value = tis_wait_reg(priv, &regs[locality].tpm_status,
260                              TIS_STS_VALID, TIS_STS_VALID);
261         if ((value == -ETIMEDOUT) || (value & TIS_STS_EXPECT)) {
262                 printf("%s:%d unexpected TPM status 0x%x\n",
263                        __FILE__, __LINE__, value);
264                 return value == -ETIMEDOUT ? value : -EIO;
265         }
266
267         /* OK, sitting pretty, let's start the command execution. */
268         tpm_write_word(priv, TIS_STS_TPM_GO, &regs[locality].tpm_status);
269         return 0;
270 }
271
272 /*
273  * tis_readresponse()
274  *
275  * read the TPM device response after a command was issued.
276  *
277  * @buffer - address where to read the response, byte by byte.
278  * @len - pointer to the size of buffer
279  *
280  * On success stores the number of received bytes to len and returns 0. On
281  * errors (misformatted TPM data or synchronization problems) returns
282  * -ve value.
283  */
284 static int tis_readresponse(struct udevice *dev, u8 *buffer, size_t len)
285 {
286         struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
287         struct tpm_locality *regs = priv->regs;
288         u16 burst;
289         u32 value;
290         u32 offset = 0;
291         u8 locality = 0;
292         const u32 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
293         u32 expected_count = len;
294         int max_cycles = 0;
295
296         /* Wait for the TPM to process the command. */
297         value = tis_wait_reg(priv, &regs[locality].tpm_status,
298                               has_data, has_data);
299         if (value == -ETIMEDOUT) {
300                 printf("%s:%d failed processing command\n",
301                        __FILE__, __LINE__);
302                 return value;
303         }
304
305         do {
306                 while ((burst = burst_count(value)) == 0) {
307                         if (max_cycles++ == MAX_DELAY_US) {
308                                 printf("%s:%d TPM stuck on read\n",
309                                        __FILE__, __LINE__);
310                                 return -EIO;
311                         }
312                         udelay(1);
313                         value = tpm_read_word(priv, &regs[locality].tpm_status);
314                 }
315
316                 max_cycles = 0;
317
318                 while (burst-- && (offset < expected_count)) {
319                         buffer[offset++] = tpm_read_byte(priv,
320                                                 &regs[locality].data);
321
322                         if (offset == 6) {
323                                 /*
324                                  * We got the first six bytes of the reply,
325                                  * let's figure out how many bytes to expect
326                                  * total - it is stored as a 4 byte number in
327                                  * network order, starting with offset 2 into
328                                  * the body of the reply.
329                                  */
330                                 u32 real_length;
331                                 memcpy(&real_length,
332                                        buffer + 2,
333                                        sizeof(real_length));
334                                 expected_count = be32_to_cpu(real_length);
335
336                                 if ((expected_count < offset) ||
337                                     (expected_count > len)) {
338                                         printf("%s:%d bad response size %d\n",
339                                                __FILE__, __LINE__,
340                                                expected_count);
341                                         return -ENOSPC;
342                                 }
343                         }
344                 }
345
346                 /* Wait for the next portion. */
347                 value = tis_wait_reg(priv, &regs[locality].tpm_status,
348                                      TIS_STS_VALID, TIS_STS_VALID);
349                 if (value == -ETIMEDOUT) {
350                         printf("%s:%d failed to read response\n",
351                                __FILE__, __LINE__);
352                         return value;
353                 }
354
355                 if (offset == expected_count)
356                         break;  /* We got all we needed. */
357
358         } while ((value & has_data) == has_data);
359
360         /*
361          * Make sure we indeed read all there was. The TIS_STS_VALID bit is
362          * known to be set.
363          */
364         if (value & TIS_STS_DATA_AVAILABLE) {
365                 printf("%s:%d wrong receive status %x\n",
366                        __FILE__, __LINE__, value);
367                 return -EBADMSG;
368         }
369
370         /* Tell the TPM that we are done. */
371         tpm_write_word(priv, TIS_STS_COMMAND_READY,
372                        &regs[locality].tpm_status);
373
374         return offset;
375 }
376
377 static int tpm_tis_lpc_open(struct udevice *dev)
378 {
379         struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
380         struct tpm_locality *regs = priv->regs;
381         u8 locality = 0; /* we use locality zero for everything. */
382         int ret;
383
384         /* now request access to locality. */
385         tpm_write_word(priv, TIS_ACCESS_REQUEST_USE, &regs[locality].access);
386
387         /* did we get a lock? */
388         ret = tis_wait_reg(priv, &regs[locality].access,
389                          TIS_ACCESS_ACTIVE_LOCALITY,
390                          TIS_ACCESS_ACTIVE_LOCALITY);
391         if (ret == -ETIMEDOUT) {
392                 printf("%s:%d - failed to lock locality %d\n",
393                        __FILE__, __LINE__, locality);
394                 return ret;
395         }
396
397         tpm_write_word(priv, TIS_STS_COMMAND_READY,
398                        &regs[locality].tpm_status);
399         return 0;
400 }
401
402 static int tpm_tis_lpc_close(struct udevice *dev)
403 {
404         struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
405         struct tpm_locality *regs = priv->regs;
406         u8 locality = 0;
407
408         if (tpm_read_word(priv, &regs[locality].access) &
409             TIS_ACCESS_ACTIVE_LOCALITY) {
410                 tpm_write_word(priv, TIS_ACCESS_ACTIVE_LOCALITY,
411                                &regs[locality].access);
412
413                 if (tis_wait_reg(priv, &regs[locality].access,
414                                  TIS_ACCESS_ACTIVE_LOCALITY, 0) == -ETIMEDOUT) {
415                         printf("%s:%d - failed to release locality %d\n",
416                                __FILE__, __LINE__, locality);
417                         return -ETIMEDOUT;
418                 }
419         }
420         return 0;
421 }
422
423 static int tpm_tis_get_desc(struct udevice *dev, char *buf, int size)
424 {
425         if (size < 50)
426                 return -ENOSPC;
427
428         return snprintf(buf, size, "1.2 TPM (vendor %s, chip %s)",
429                         "Infineon", "SLB9635 TT 1.2");
430 }
431
432
433 static const struct tpm_ops tpm_tis_lpc_ops = {
434         .open           = tpm_tis_lpc_open,
435         .close          = tpm_tis_lpc_close,
436         .get_desc       = tpm_tis_get_desc,
437         .send           = tis_senddata,
438         .recv           = tis_readresponse,
439 };
440
441 static const struct udevice_id tpm_tis_lpc_ids[] = {
442         { .compatible = "infineon,slb9635lpc" },
443         { }
444 };
445
446 U_BOOT_DRIVER(tpm_tis_lpc) = {
447         .name   = "tpm_tis_lpc",
448         .id     = UCLASS_TPM,
449         .of_match = tpm_tis_lpc_ids,
450         .ops    = &tpm_tis_lpc_ops,
451         .probe  = tpm_tis_lpc_probe,
452         .priv_auto_alloc_size = sizeof(struct tpm_tis_lpc_priv),
453 };