1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2022, Linaro Limited
4  */
5 
6 #include <drivers/tpm2_mmio.h>
7 #include <drivers/tpm2_ptp_fifo.h>
8 #include <io.h>
9 #include <kernel/dt.h>
10 #include <trace.h>
11 
12 static vaddr_t tpm2_mmio_base;
13 
tpm2_mmio_rx32(struct tpm2_chip * chip __unused,uint32_t adr,uint32_t * buf)14 static enum tpm2_result tpm2_mmio_rx32(struct tpm2_chip *chip __unused,
15 				       uint32_t adr, uint32_t *buf)
16 {
17 	*buf = io_read32(tpm2_mmio_base + adr);
18 
19 	return TPM2_OK;
20 }
21 
tpm2_mmio_tx32(struct tpm2_chip * chip __unused,uint32_t adr,uint32_t val)22 static enum tpm2_result tpm2_mmio_tx32(struct tpm2_chip *chip __unused,
23 				       uint32_t adr, uint32_t val)
24 {
25 	io_write32(tpm2_mmio_base + adr, val);
26 
27 	return TPM2_OK;
28 }
29 
tpm2_mmio_rx8(struct tpm2_chip * chip __unused,uint32_t adr,uint16_t len,uint8_t * buf)30 static enum tpm2_result tpm2_mmio_rx8(struct tpm2_chip *chip __unused,
31 				      uint32_t adr, uint16_t len, uint8_t *buf)
32 {
33 	unsigned int n = 0;
34 
35 	for (n = 0; n < len; n++)
36 		buf[n] = io_read8(tpm2_mmio_base + adr);
37 
38 	return TPM2_OK;
39 }
40 
tpm2_mmio_tx8(struct tpm2_chip * chip __unused,uint32_t adr,uint16_t len,uint8_t * buf)41 static enum tpm2_result tpm2_mmio_tx8(struct tpm2_chip *chip __unused,
42 				      uint32_t adr, uint16_t len, uint8_t *buf)
43 {
44 	while (len--)
45 		io_write8(tpm2_mmio_base + adr, *buf++);
46 
47 	return TPM2_OK;
48 }
49 
50 static const struct tpm2_ptp_phy_ops tpm2_mmio_ops = {
51 	.rx32 = tpm2_mmio_rx32,
52 	.tx32 = tpm2_mmio_tx32,
53 	.rx8 = tpm2_mmio_rx8,
54 	.tx8 = tpm2_mmio_tx8,
55 };
56 
57 static const struct tpm2_ptp_ops tpm2_fifo_ops = {
58 	.init = tpm2_fifo_init,
59 	.end = tpm2_fifo_end,
60 	.send = tpm2_fifo_send,
61 	.recv = tpm2_fifo_recv,
62 };
63 
64 static struct tpm2_chip tpm2_mmio_chip = {
65 	.phy_ops = &tpm2_mmio_ops,
66 	.ops = &tpm2_fifo_ops,
67 };
68 
tpm2_mmio_init(paddr_t pbase)69 enum tpm2_result tpm2_mmio_init(paddr_t pbase)
70 {
71 	enum tpm2_result ret = TPM2_OK;
72 	struct io_pa_va base = { };
73 
74 	base.pa = pbase;
75 
76 	tpm2_mmio_base = io_pa_or_va_secure(&base, TPM2_REG_SIZE);
77 	assert(tpm2_mmio_base);
78 
79 	DMSG("TPM2 MMIO pbase: 0x%" PRIxPA, base.pa);
80 	DMSG("TPM2 MMIO vbase: 0x%" PRIxVA, base.va);
81 
82 	ret = tpm2_chip_register(&tpm2_mmio_chip);
83 	if (ret) {
84 		EMSG("Init failed");
85 		return ret;
86 	}
87 
88 	return TPM2_OK;
89 }
90