• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017 - 2020, Broadcom
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stdint.h>
8 
9 #include <common/debug.h>
10 #include <drivers/delay_timer.h>
11 #include <lib/mmio.h>
12 
13 #include <ocotp.h>
14 #include <platform_def.h>
15 
16 #define OTP_MAP 2
17 #define OTP_NUM_WORDS 2048
18 /*
19  * # of tries for OTP Status. The time to execute a command varies. The slowest
20  * commands are writes which also vary based on the # of bits turned on. Writing
21  * 0xffffffff takes ~3800 us.
22  */
23 #define OTPC_RETRIES_US                 5000
24 
25 /* Sequence to enable OTP program */
26 #define OTPC_PROG_EN_SEQ             { 0xf, 0x4, 0x8, 0xd }
27 
28 /* OTPC Commands */
29 #define OTPC_CMD_READ                0x0
30 #define OTPC_CMD_OTP_PROG_ENABLE     0x2
31 #define OTPC_CMD_OTP_PROG_DISABLE    0x3
32 #define OTPC_CMD_PROGRAM             0x8
33 #define OTPC_CMD_ECC                 0x10
34 #define OTPC_ECC_ADDR                0x1A
35 #define OTPC_ECC_VAL                 0x00EC0000
36 
37 /* OTPC Status Bits */
38 #define OTPC_STAT_CMD_DONE           BIT(1)
39 #define OTPC_STAT_PROG_OK            BIT(2)
40 
41 /* OTPC register definition */
42 #define OTPC_MODE_REG_OFFSET         0x0
43 #define OTPC_MODE_REG_OTPC_MODE      0
44 #define OTPC_COMMAND_OFFSET          0x4
45 #define OTPC_COMMAND_COMMAND_WIDTH   6
46 #define OTPC_CMD_START_OFFSET        0x8
47 #define OTPC_CMD_START_START         0
48 #define OTPC_CPU_STATUS_OFFSET       0xc
49 #define OTPC_CPUADDR_REG_OFFSET      0x28
50 #define OTPC_CPUADDR_REG_OTPC_CPU_ADDRESS_WIDTH 16
51 #define OTPC_CPU_WRITE_REG_OFFSET    0x2c
52 
53 #define OTPC_CMD_MASK  (BIT(OTPC_COMMAND_COMMAND_WIDTH) - 1)
54 #define OTPC_ADDR_MASK (BIT(OTPC_CPUADDR_REG_OTPC_CPU_ADDRESS_WIDTH) - 1)
55 
56 #define OTPC_MODE_REG			OCOTP_REGS_BASE
57 
58 struct chip_otp_cfg {
59 	uint32_t base;
60 	uint32_t num_words;
61 };
62 
63 struct chip_otp_cfg ocotp_cfg = {
64 	.base = OTPC_MODE_REG,
65 	.num_words = 2048,
66 };
67 
68 struct otpc_priv {
69 	uint32_t base;
70 	struct otpc_map *map;
71 	int size;
72 	int state;
73 };
74 
75 struct otpc_priv otpc_info;
76 
set_command(uint32_t base,uint32_t command)77 static inline void set_command(uint32_t base, uint32_t command)
78 {
79 	mmio_write_32(base + OTPC_COMMAND_OFFSET, command & OTPC_CMD_MASK);
80 }
81 
set_cpu_address(uint32_t base,uint32_t addr)82 static inline void set_cpu_address(uint32_t base, uint32_t addr)
83 {
84 	mmio_write_32(base + OTPC_CPUADDR_REG_OFFSET, addr & OTPC_ADDR_MASK);
85 }
86 
set_start_bit(uint32_t base)87 static inline void set_start_bit(uint32_t base)
88 {
89 	mmio_write_32(base + OTPC_CMD_START_OFFSET, 1 << OTPC_CMD_START_START);
90 }
91 
reset_start_bit(uint32_t base)92 static inline void reset_start_bit(uint32_t base)
93 {
94 	mmio_write_32(base + OTPC_CMD_START_OFFSET, 0);
95 }
96 
write_cpu_data(uint32_t base,uint32_t value)97 static inline void write_cpu_data(uint32_t base, uint32_t value)
98 {
99 	mmio_write_32(base + OTPC_CPU_WRITE_REG_OFFSET, value);
100 }
101 
poll_cpu_status(uint32_t base,uint32_t value)102 static int poll_cpu_status(uint32_t base, uint32_t value)
103 {
104 	uint32_t status;
105 	uint32_t retries;
106 
107 	for (retries = 0; retries < OTPC_RETRIES_US; retries++) {
108 		status = mmio_read_32(base + OTPC_CPU_STATUS_OFFSET);
109 		if (status & value)
110 			break;
111 		udelay(1);
112 	}
113 	if (retries == OTPC_RETRIES_US)
114 		return -1;
115 
116 	return 0;
117 }
118 
bcm_otpc_ecc(uint32_t enable)119 static int bcm_otpc_ecc(uint32_t enable)
120 {
121 	struct otpc_priv *priv = &otpc_info;
122 	int ret;
123 
124 	set_command(priv->base, OTPC_CMD_ECC);
125 	set_cpu_address(priv->base, OTPC_ECC_ADDR);
126 
127 	if (!enable)
128 		write_cpu_data(priv->base, OTPC_ECC_VAL);
129 	else
130 		write_cpu_data(priv->base, ~OTPC_ECC_VAL);
131 
132 	set_start_bit(priv->base);
133 	ret = poll_cpu_status(priv->base, OTPC_STAT_CMD_DONE);
134 	if (ret) {
135 		ERROR("otp ecc op error: 0x%x", ret);
136 		return -1;
137 	}
138 	reset_start_bit(priv->base);
139 
140 	return 0;
141 }
142 
143 /*
144  * bcm_otpc_read read otp data in the size of 8 byte rows.
145  * bytes has to be the multiple of 8.
146  * return -1 in error case, return read bytes in success.
147  */
bcm_otpc_read(unsigned int offset,void * val,uint32_t bytes,uint32_t ecc_flag)148 int bcm_otpc_read(unsigned int offset, void *val, uint32_t bytes,
149 		  uint32_t ecc_flag)
150 {
151 	struct otpc_priv *priv = &otpc_info;
152 	uint32_t *buf = val;
153 	uint32_t bytes_read;
154 	uint32_t address = offset / priv->map->word_size;
155 	int i, ret;
156 
157 	if (!priv->state) {
158 		ERROR("OCOTP read failed\n");
159 		return -1;
160 	}
161 
162 	bcm_otpc_ecc(ecc_flag);
163 
164 	for (bytes_read = 0; (bytes_read + priv->map->word_size) <= bytes;) {
165 		set_command(priv->base, OTPC_CMD_READ);
166 		set_cpu_address(priv->base, address++);
167 		set_start_bit(priv->base);
168 		ret = poll_cpu_status(priv->base, OTPC_STAT_CMD_DONE);
169 		if (ret) {
170 			ERROR("otp read error: 0x%x", ret);
171 			return -1;
172 		}
173 
174 		for (i = 0; i < priv->map->otpc_row_size; i++) {
175 			*buf++ = mmio_read_32(priv->base +
176 					priv->map->data_r_offset[i]);
177 			bytes_read += sizeof(*buf);
178 		}
179 
180 		reset_start_bit(priv->base);
181 	}
182 
183 	return bytes_read;
184 }
185 
bcm_otpc_init(struct otpc_map * map)186 int bcm_otpc_init(struct otpc_map *map)
187 {
188 	struct otpc_priv *priv;
189 
190 	priv = &otpc_info;
191 	priv->base = ocotp_cfg.base;
192 	priv->map = map;
193 
194 	priv->size = 4 * ocotp_cfg.num_words;
195 
196 	/* Enable CPU access to OTPC. */
197 	mmio_setbits_32(priv->base + OTPC_MODE_REG_OFFSET,
198 			BIT(OTPC_MODE_REG_OTPC_MODE));
199 	reset_start_bit(priv->base);
200 	priv->state = 1;
201 	VERBOSE("OTPC Initialization done\n");
202 
203 	return 0;
204 }
205