xref: /optee_os/core/arch/arm/plat-telechips/drivers/tcc_otp.c (revision c1e657096ec2f9ad6a373ac3265600252689933e)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2024, Telechips Inc.
4  */
5 
6 #include <drivers/tcc_otp.h>
7 #include <io.h>
8 #include <kernel/delay.h>
9 #include <mm/core_memprot.h>
10 #include <otprom.h>
11 #include <string.h>
12 
13 #define OTP_CTRL_SIZE		U(0x1000)
14 #define OTP_CMD_SIZE		U(0x1000)
15 
16 #define GENERAL_STATUS		U(0x0)
17 #define READ_STATUS		U(0x4)
18 #define PROG_STATUS		U(0x8)
19 #define OTP_ADDRESS		U(0x10)
20 #define OTP_CONTROL		U(0x14)
21 #define READ_DATA_PAYLOAD0	U(0x20)
22 #define READ_DATA_PAYLOAD1	U(0x24)
23 #define READ_DATA_PAYLOAD2	U(0x28)
24 #define READ_DATA_PAYLOAD3	U(0x2C)
25 #define READ_ADMIN_INFO0	U(0x30)
26 #define READ_ADMIN_INFO1	U(0x34)
27 #define READ_ADMIN_INFO2	U(0x38)
28 #define READ_ADMIN_INFO3	U(0x3C)
29 #define PROG_DATA_PAYLOAD0	U(0x40)
30 #define PROG_DATA_PAYLOAD1	U(0x44)
31 #define PROG_DATA_PAYLOAD2	U(0x48)
32 #define PROG_DATA_PAYLOAD3	U(0x4C)
33 #define PROG_ADMIN_INFO0	U(0x50)
34 #define PROG_ADMIN_INFO1	U(0x54)
35 #define PROG_ADMIN_INFO2	U(0x58)
36 #define PROG_ADMIN_INFO3	U(0x5C)
37 
38 /* GENERAL_STATUS */
39 #define STATUS_READY		BIT(0)
40 
41 /* READ_STATUS */
42 #define DATA_ERR		BIT(3)
43 #define PERMISSION_ERR          BIT(0)
44 
45 /* OTP_CONTROL Register */
46 #define CTRL_DONE		BIT(16)
47 #define CTRL_START		BIT(0)
48 #define CTRL_CMD_PROG		SHIFT_U32(0xA, 4)
49 #define CTRL_CMD_READ		SHIFT_U32(0xF, 4)
50 
51 /* Admin Info */
52 #define ADMIN_VALID		BIT(0)
53 
54 /* Write Protection Control */
55 #define EXT_WP			BIT(30)
56 #define SOFT_WP			BIT(3)
57 
58 #define IS_16BYTE_ALIGNED(x)	IS_ALIGNED(x, 16)
59 
60 register_phys_mem(MEM_AREA_IO_SEC, OTP_CMD_BASE, OTP_CMD_SIZE);
61 
wait_for_ready(vaddr_t reg)62 static void wait_for_ready(vaddr_t reg)
63 {
64 	while (!(io_read32(reg + GENERAL_STATUS) & STATUS_READY))
65 		udelay(1);
66 }
67 
wait_for_done(vaddr_t reg)68 static void wait_for_done(vaddr_t reg)
69 {
70 	while (!(io_read32(reg + OTP_CONTROL) & CTRL_DONE))
71 		udelay(1);
72 }
73 
tcc_otp_read_128(uint32_t offset,uint32_t * buf)74 TEE_Result tcc_otp_read_128(uint32_t offset, uint32_t *buf)
75 {
76 	vaddr_t reg = (vaddr_t)phys_to_virt_io(OTP_CMD_BASE, OTP_CMD_SIZE);
77 	uint32_t status = 0;
78 	uint32_t admin_info0 = 0;
79 
80 	if (!IS_16BYTE_ALIGNED(offset) || offset >= OTPROM_128_LIMIT ||
81 	    offset < OTPROM_128_START || !buf || !reg) {
82 		EMSG("Invalid parameters");
83 		return TEE_ERROR_BAD_PARAMETERS;
84 	}
85 
86 	wait_for_ready(reg);
87 	io_write32(reg + OTP_ADDRESS, offset);
88 	io_write32(reg + OTP_CONTROL, CTRL_CMD_READ | CTRL_START);
89 	wait_for_done(reg);
90 
91 	admin_info0 = io_read32(reg + READ_ADMIN_INFO0);
92 	if (!(admin_info0 & ADMIN_VALID)) {
93 		if (!admin_info0 && !io_read32(reg + READ_STATUS))
94 			return TEE_ERROR_NO_DATA;
95 		return TEE_ERROR_BAD_STATE;
96 	}
97 
98 	status = io_read32(reg + READ_STATUS);
99 	if (status & (DATA_ERR | PERMISSION_ERR)) {
100 		EMSG("Failed to read OTP (%#"PRIx32")", status);
101 		return TEE_ERROR_BAD_STATE;
102 	}
103 
104 	buf[0] = io_read32(reg + READ_DATA_PAYLOAD0);
105 	buf[1] = io_read32(reg + READ_DATA_PAYLOAD1);
106 	buf[2] = io_read32(reg + READ_DATA_PAYLOAD2);
107 	buf[3] = io_read32(reg + READ_DATA_PAYLOAD3);
108 
109 	return TEE_SUCCESS;
110 }
111 
tcc_otp_write_128(uint32_t offset,const uint32_t * buf)112 TEE_Result tcc_otp_write_128(uint32_t offset, const uint32_t *buf)
113 {
114 	vaddr_t reg = (vaddr_t)phys_to_virt_io(OTP_CMD_BASE, OTP_CMD_SIZE);
115 	vaddr_t ctrl = (vaddr_t)phys_to_virt_io(OTP_CTRL_BASE, OTP_CTRL_SIZE);
116 
117 	if (!IS_16BYTE_ALIGNED(offset) || offset >= OTPROM_128_LIMIT ||
118 	    offset < OTPROM_128_START || !buf || !reg) {
119 		EMSG("Invalid parameters");
120 		return TEE_ERROR_BAD_PARAMETERS;
121 	}
122 
123 	if (io_read32(ctrl) & EXT_WP) {
124 		EMSG("EXT_WP is high");
125 		return TEE_ERROR_BAD_STATE;
126 	}
127 
128 	wait_for_ready(reg);
129 	io_clrbits32(ctrl, SOFT_WP);
130 	io_write32(reg + OTP_ADDRESS, offset);
131 	io_write32(reg + PROG_DATA_PAYLOAD0, buf[0]);
132 	io_write32(reg + PROG_DATA_PAYLOAD1, buf[1]);
133 	io_write32(reg + PROG_DATA_PAYLOAD2, buf[2]);
134 	io_write32(reg + PROG_DATA_PAYLOAD3, buf[3]);
135 	io_write32(reg + PROG_ADMIN_INFO0, 0);
136 	io_write32(reg + PROG_ADMIN_INFO1, 0);
137 	io_write32(reg + PROG_ADMIN_INFO2, 0);
138 	io_write32(reg + PROG_ADMIN_INFO3, 0);
139 	io_write32(reg + OTP_CONTROL, CTRL_CMD_PROG | CTRL_START);
140 	wait_for_done(reg);
141 	io_setbits32(ctrl, SOFT_WP);
142 
143 	return  TEE_SUCCESS;
144 }
145