Angel Pons | bbc99cf | 2020-04-04 18:51:23 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 2 | |
Kyösti Mälkki | 13f6650 | 2019-03-03 08:01:05 +0200 | [diff] [blame] | 3 | #include <device/mmio.h> |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 4 | #include <assert.h> |
Elyes HAOUAS | 20eaef0 | 2019-03-29 17:45:28 +0100 | [diff] [blame] | 5 | #include <console/console.h> |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 6 | #include <delay.h> |
| 7 | #include <soc/addressmap.h> |
| 8 | #include <soc/soc.h> |
| 9 | #include <types.h> |
| 10 | #include <vb2_api.h> |
| 11 | |
| 12 | enum rk3288_crypto_interrupt_bits { |
| 13 | PKA_DONE = 1 << 5, |
| 14 | HASH_DONE = 1 << 4, |
| 15 | HRDMA_ERR = 1 << 3, |
| 16 | HRDMA_DONE = 1 << 2, |
| 17 | BCDMA_ERR = 1 << 1, |
| 18 | BCDMA_DONE = 1 << 0, |
| 19 | }; |
| 20 | |
| 21 | struct rk3288_crypto { |
| 22 | u32 intsts; |
| 23 | u32 intena; |
| 24 | u32 ctrl; |
| 25 | u32 conf; |
| 26 | u32 brdmas; |
| 27 | u32 btdmas; |
| 28 | u32 btdmal; |
| 29 | u32 hrdmas; |
| 30 | u32 hrdmal; |
| 31 | u8 _res0[0x80 - 0x24]; |
| 32 | u32 aes_ctrl; |
| 33 | u32 aes_sts; |
| 34 | u32 aes_din[4]; |
| 35 | u32 aes_dout[4]; |
| 36 | u32 aes_iv[4]; |
| 37 | u32 aes_key[8]; |
| 38 | u32 aes_cnt[4]; |
| 39 | u8 _res1[0x100 - 0xe8]; |
| 40 | u32 tdes_ctrl; |
| 41 | u32 tdes_sts; |
| 42 | u32 tdes_din[2]; |
| 43 | u32 tdes_dout[2]; |
| 44 | u32 tdes_iv[2]; |
| 45 | u32 tdes_key[3][2]; |
| 46 | u8 _res2[0x180 - 0x138]; |
| 47 | u32 hash_ctrl; |
| 48 | u32 hash_sts; |
| 49 | u32 hash_msg_len; |
| 50 | u32 hash_dout[8]; |
| 51 | u32 hash_seed[5]; |
| 52 | u8 _res3[0x200 - 0x1c0]; |
| 53 | u32 trng_ctrl; |
| 54 | u32 trng_dout[8]; |
| 55 | } *crypto = (void *)CRYPTO_BASE; |
| 56 | check_member(rk3288_crypto, trng_dout[7], 0x220); |
| 57 | |
Joel Kitching | 220ac04 | 2019-07-31 14:19:00 +0800 | [diff] [blame] | 58 | vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg, |
| 59 | uint32_t data_size) |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 60 | { |
Julius Werner | 99a9928 | 2022-08-09 18:46:50 -0700 | [diff] [blame] | 61 | if (hash_alg != VB2_HASH_SHA256 || !data_size) |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 62 | return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED; |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 63 | |
Julius Werner | 2f37bd6 | 2015-02-19 14:51:15 -0800 | [diff] [blame] | 64 | write32(&crypto->ctrl, RK_SETBITS(1 << 6)); /* Assert HASH_FLUSH */ |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 65 | udelay(1); /* for 10+ cycles to */ |
Julius Werner | 2f37bd6 | 2015-02-19 14:51:15 -0800 | [diff] [blame] | 66 | write32(&crypto->ctrl, RK_CLRBITS(1 << 6)); /* clear out old hash */ |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 67 | |
| 68 | /* Enable DMA byte swapping for little-endian bus (Byteswap_??FIFO) */ |
Julius Werner | 2f37bd6 | 2015-02-19 14:51:15 -0800 | [diff] [blame] | 69 | write32(&crypto->conf, 1 << 5 | 1 << 4 | 1 << 3); |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 70 | |
Julius Werner | 2f37bd6 | 2015-02-19 14:51:15 -0800 | [diff] [blame] | 71 | write32(&crypto->intena, HRDMA_ERR | HRDMA_DONE); /* enable interrupt */ |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 72 | |
Julius Werner | 2f37bd6 | 2015-02-19 14:51:15 -0800 | [diff] [blame] | 73 | write32(&crypto->hash_msg_len, data_size); /* program total size */ |
| 74 | write32(&crypto->hash_ctrl, 1 << 3 | 0x2); /* swap DOUT, SHA256 */ |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 75 | |
| 76 | printk(BIOS_DEBUG, "Initialized RK3288 HW crypto for %u byte SHA256\n", |
| 77 | data_size); |
| 78 | return VB2_SUCCESS; |
| 79 | } |
| 80 | |
Joel Kitching | 220ac04 | 2019-07-31 14:19:00 +0800 | [diff] [blame] | 81 | vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size) |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 82 | { |
| 83 | uint32_t intsts; |
| 84 | |
Julius Werner | 2f37bd6 | 2015-02-19 14:51:15 -0800 | [diff] [blame] | 85 | write32(&crypto->intsts, HRDMA_ERR | HRDMA_DONE); /* clear interrupts */ |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 86 | |
| 87 | /* NOTE: This assumes that the DMA is reading from uncached SRAM. */ |
Julius Werner | 2f37bd6 | 2015-02-19 14:51:15 -0800 | [diff] [blame] | 88 | write32(&crypto->hrdmas, (uint32_t)buf); |
| 89 | write32(&crypto->hrdmal, size / sizeof(uint32_t)); |
| 90 | write32(&crypto->ctrl, RK_SETBITS(1 << 3)); /* Set HASH_START */ |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 91 | do { |
| 92 | intsts = read32(&crypto->intsts); |
| 93 | if (intsts & HRDMA_ERR) { |
Julius Werner | e966595 | 2022-01-21 17:06:20 -0800 | [diff] [blame] | 94 | printk(BIOS_ERR, "DMA error during HW crypto\n"); |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 95 | return VB2_ERROR_UNKNOWN; |
| 96 | } |
| 97 | } while (!(intsts & HRDMA_DONE)); /* wait for DMA to finish */ |
| 98 | |
| 99 | return VB2_SUCCESS; |
| 100 | } |
| 101 | |
Joel Kitching | 220ac04 | 2019-07-31 14:19:00 +0800 | [diff] [blame] | 102 | vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest, |
| 103 | uint32_t digest_size) |
Julius Werner | 33df495 | 2014-12-16 22:48:26 -0800 | [diff] [blame] | 104 | { |
| 105 | uint32_t *dest = (uint32_t *)digest; |
| 106 | uint32_t *src = crypto->hash_dout; |
| 107 | assert(digest_size == sizeof(crypto->hash_dout)); |
| 108 | |
| 109 | while (!(read32(&crypto->hash_sts) & 0x1)) |
| 110 | /* wait for crypto engine to set HASH_DONE bit */; |
| 111 | |
| 112 | while ((uint8_t *)dest < digest + digest_size) |
| 113 | *dest++ = read32(src++); |
| 114 | |
| 115 | return VB2_SUCCESS; |
| 116 | } |