xref: /optee_os/core/drivers/bcm_sotp.c (revision 0d77037f5943c86560dd7c8f473fbc6a55d60a34)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2019 Broadcom.
4  */
5 
6 #include <assert.h>
7 #include <drivers/bcm_sotp.h>
8 #include <initcall.h>
9 #include <io.h>
10 #include <kernel/delay.h>
11 #include <mm/core_memprot.h>
12 #include <platform_config.h>
13 #include <util.h>
14 
15 #define SOTP_PROG_CONTROL			0x0
16 #define SOTP_PROG_CONTROL__OTP_CPU_MODE_EN	BIT(15)
17 #define SOTP_PROG_CONTROL__OTP_DISABLE_ECC	BIT(9)
18 #define SOTP_ADDR__OTP_ROW_ADDR_R		6
19 
20 #define SOTP_ADDR				0xc
21 
22 #define SOTP_CTRL_0				0x10
23 #define SOTP_CTRL_0__START			1
24 #define SOTP_READ				0
25 
26 #define SOTP_STAT_0				0x18
27 #define SOTP_STATUS_0__FDONE			BIT(3)
28 
29 #define SOTP_STATUS_1				0x1c
30 #define SOTP_STATUS_1__CMD_DONE			BIT(1)
31 #define SOTP_STATUS_1__ECC_DET			BIT(17)
32 
33 #define SOTP_RDDATA_0				0x20
34 #define SOTP_RDDATA_1				0x24
35 #define SOTP_ADDR_MASK				0x3ff
36 
37 #define SOTP_ECC_ERR_DETECT			BIT64(63)
38 
39 #define SOTP_TIMEOUT_US				300
40 
41 static vaddr_t bcm_sotp_base;
42 
43 static TEE_Result otp_status_done_wait(vaddr_t addr, uint32_t bit)
44 {
45 	uint64_t timeout = timeout_init_us(SOTP_TIMEOUT_US);
46 
47 	while (!(io_read32(addr) & bit))
48 		if (timeout_elapsed(timeout))
49 			return TEE_ERROR_BUSY;
50 	return TEE_SUCCESS;
51 }
52 
53 TEE_Result bcm_iproc_sotp_mem_read(uint32_t row_addr, uint32_t sotp_add_ecc,
54 				uint64_t *rdata)
55 {
56 	uint64_t read_data = 0;
57 	uint32_t reg_val = 0;
58 	TEE_Result ret = TEE_SUCCESS;
59 
60 	assert(bcm_sotp_base);
61 	/* Check for FDONE status */
62 	ret = otp_status_done_wait((bcm_sotp_base + SOTP_STAT_0),
63 				   SOTP_STATUS_0__FDONE);
64 	if (ret) {
65 		EMSG("FDONE status done wait failed");
66 		return ret;
67 	}
68 
69 	/* Enable OTP access by CPU */
70 	io_setbits32((bcm_sotp_base + SOTP_PROG_CONTROL),
71 		     SOTP_PROG_CONTROL__OTP_CPU_MODE_EN);
72 
73 	if (sotp_add_ecc == 1) {
74 		io_clrbits32((bcm_sotp_base + SOTP_PROG_CONTROL),
75 			     SOTP_PROG_CONTROL__OTP_DISABLE_ECC);
76 	} else {
77 		io_setbits32((bcm_sotp_base + SOTP_PROG_CONTROL),
78 			     SOTP_PROG_CONTROL__OTP_DISABLE_ECC);
79 	}
80 
81 	/* 10 bit row address */
82 	reg_val = (row_addr & SOTP_ADDR_MASK) << SOTP_ADDR__OTP_ROW_ADDR_R;
83 	io_write32((bcm_sotp_base + SOTP_ADDR), reg_val);
84 	reg_val = SOTP_READ;
85 	io_write32((bcm_sotp_base + SOTP_CTRL_0), reg_val);
86 
87 	/* Start bit to tell SOTP to send command to the OTP controller */
88 	io_setbits32((bcm_sotp_base + SOTP_CTRL_0), SOTP_CTRL_0__START);
89 
90 	/* Wait for SOTP command done to be set */
91 	ret = otp_status_done_wait((bcm_sotp_base + SOTP_STAT_0),
92 				   SOTP_STATUS_1__CMD_DONE);
93 	if (ret) {
94 		EMSG("FDONE cmd done wait failed\n");
95 		return ret;
96 	}
97 
98 	DMSG("CMD Done\n");
99 
100 	/* Clr Start bit after command done */
101 	io_clrbits32((bcm_sotp_base + SOTP_CTRL_0), SOTP_CTRL_0__START);
102 	read_data = io_read32(bcm_sotp_base + SOTP_RDDATA_1);
103 	read_data = ((read_data & 0x1ff) << 32);
104 	read_data |= io_read32(bcm_sotp_base + SOTP_RDDATA_0);
105 
106 	reg_val = io_read32(bcm_sotp_base + SOTP_STATUS_1);
107 	/* no ECC check till row 15 */
108 	if ((row_addr > 15) && (reg_val & SOTP_STATUS_1__ECC_DET)) {
109 		EMSG("SOTP ECC ERROR Detected ROW %d\n", row_addr);
110 		read_data = SOTP_ECC_ERR_DETECT;
111 	}
112 
113 	/* Command done is cleared */
114 	io_setbits32((bcm_sotp_base + SOTP_STATUS_1), SOTP_STATUS_1__CMD_DONE);
115 	io_clrbits32((bcm_sotp_base + SOTP_PROG_CONTROL),
116 		     SOTP_PROG_CONTROL__OTP_CPU_MODE_EN);
117 	DMSG("read done\n");
118 
119 	*rdata = read_data;
120 	return ret;
121 }
122 
123 static TEE_Result bcm_sotp_init(void)
124 {
125 	bcm_sotp_base = (vaddr_t)phys_to_virt(SOTP_BASE, MEM_AREA_IO_SEC);
126 
127 	DMSG("bcm_sotp init done\n");
128 	return TEE_SUCCESS;
129 }
130 
131 driver_init(bcm_sotp_init);
132