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