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
otp_status_done_wait(vaddr_t addr,uint32_t bit)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
bcm_iproc_sotp_mem_read(uint32_t row_addr,uint32_t sotp_add_ecc,uint64_t * rdata)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 /* ROWS does not support ECC */
74 if (row_addr <= SOTP_NO_ECC_ROWS)
75 sotp_add_ecc = 0;
76
77 if (sotp_add_ecc == 1) {
78 io_clrbits32((bcm_sotp_base + SOTP_PROG_CONTROL),
79 SOTP_PROG_CONTROL__OTP_DISABLE_ECC);
80 } else {
81 io_setbits32((bcm_sotp_base + SOTP_PROG_CONTROL),
82 SOTP_PROG_CONTROL__OTP_DISABLE_ECC);
83 }
84
85 /* 10 bit row address */
86 reg_val = (row_addr & SOTP_ADDR_MASK) << SOTP_ADDR__OTP_ROW_ADDR_R;
87 io_write32((bcm_sotp_base + SOTP_ADDR), reg_val);
88 reg_val = SOTP_READ;
89 io_write32((bcm_sotp_base + SOTP_CTRL_0), reg_val);
90
91 /* Start bit to tell SOTP to send command to the OTP controller */
92 io_setbits32((bcm_sotp_base + SOTP_CTRL_0), SOTP_CTRL_0__START);
93
94 /* Wait for SOTP command done to be set */
95 ret = otp_status_done_wait((bcm_sotp_base + SOTP_STAT_0),
96 SOTP_STATUS_1__CMD_DONE);
97 if (ret) {
98 EMSG("FDONE cmd done wait failed\n");
99 return ret;
100 }
101
102 DMSG("CMD Done\n");
103
104 /* Clr Start bit after command done */
105 io_clrbits32((bcm_sotp_base + SOTP_CTRL_0), SOTP_CTRL_0__START);
106 read_data = io_read32(bcm_sotp_base + SOTP_RDDATA_1);
107 read_data = ((read_data & 0x1ff) << 32);
108 read_data |= io_read32(bcm_sotp_base + SOTP_RDDATA_0);
109
110 reg_val = io_read32(bcm_sotp_base + SOTP_STATUS_1);
111 /* No ECC check till SOTP_NO_ECC_ROWS */
112 if (row_addr > SOTP_NO_ECC_ROWS &&
113 reg_val & SOTP_STATUS_1__ECC_DET) {
114 EMSG("SOTP ECC ERROR Detected ROW %d\n", row_addr);
115 read_data = SOTP_ECC_ERR_DETECT;
116 }
117
118 /* Command done is cleared */
119 io_setbits32((bcm_sotp_base + SOTP_STATUS_1), SOTP_STATUS_1__CMD_DONE);
120 io_clrbits32((bcm_sotp_base + SOTP_PROG_CONTROL),
121 SOTP_PROG_CONTROL__OTP_CPU_MODE_EN);
122 DMSG("read done\n");
123
124 *rdata = read_data;
125 return ret;
126 }
127
bcm_sotp_init(void)128 static TEE_Result bcm_sotp_init(void)
129 {
130 bcm_sotp_base = (vaddr_t)phys_to_virt(SOTP_BASE, MEM_AREA_IO_SEC, 1);
131
132 DMSG("bcm_sotp init done\n");
133 return TEE_SUCCESS;
134 }
135
136 service_init(bcm_sotp_init);
137