Blame view

env/sf.c 6.68 KB
83d290c56   Tom Rini   SPDX: Convert all...
1
  // SPDX-License-Identifier: GPL-2.0+
8c66497e0   Haavard Skinnemoen   Add support for e...
2
  /*
ea882baf9   Wolfgang Denk   New implementatio...
3
   * (C) Copyright 2000-2010
8c66497e0   Haavard Skinnemoen   Add support for e...
4
5
6
7
8
9
   * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   *
   * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
   * Andreas Heppel <aheppel@sysgo.de>
   *
   * (C) Copyright 2008 Atmel Corporation
8c66497e0   Haavard Skinnemoen   Add support for e...
10
11
   */
  #include <common.h>
9d922450a   Simon Glass   dm: Use dm.h head...
12
  #include <dm.h>
0ac7d722e   Simon Glass   env: Move get/set...
13
  #include <env.h>
f3998fdc4   Simon Glass   env: Rename envir...
14
  #include <env_internal.h>
5b3375ac8   Mike Frysinger   env_sf: support e...
15
  #include <malloc.h>
843c9e879   Simon Glass   dm: Add spi.h hea...
16
  #include <spi.h>
8c66497e0   Haavard Skinnemoen   Add support for e...
17
  #include <spi_flash.h>
ea882baf9   Wolfgang Denk   New implementatio...
18
19
  #include <search.h>
  #include <errno.h>
19c31285a   Gong Qianyu   dm: env_sf: fix s...
20
  #include <dm/device-internal.h>
3db711085   Simon Glass   crc32: Use the cr...
21
  #include <u-boot/crc.h>
8c66497e0   Haavard Skinnemoen   Add support for e...
22

4415f1d1f   Simon Glass   env: Create a loc...
23
24
  #ifndef CONFIG_SPL_BUILD
  #define CMD_SAVEENV
b500c92b7   Ashish Kumar   env: sf: Add supp...
25
  #define INITENV
4415f1d1f   Simon Glass   env: Create a loc...
26
  #endif
7319bcaf8   Wolfgang Wegner   add redundant env...
27
  #ifdef CONFIG_ENV_OFFSET_REDUND
4415f1d1f   Simon Glass   env: Create a loc...
28
  #ifdef CMD_SAVEENV
eb58a7fc7   Igor Grinberg   env: clean env_sf...
29
30
  static ulong env_offset		= CONFIG_ENV_OFFSET;
  static ulong env_new_offset	= CONFIG_ENV_OFFSET_REDUND;
4415f1d1f   Simon Glass   env: Create a loc...
31
  #endif
7319bcaf8   Wolfgang Wegner   add redundant env...
32

a3110f01c   Stefano Babic   env_sf: updated t...
33
  #endif /* CONFIG_ENV_OFFSET_REDUND */
7319bcaf8   Wolfgang Wegner   add redundant env...
34

8c66497e0   Haavard Skinnemoen   Add support for e...
35
  DECLARE_GLOBAL_DATA_PTR;
8c66497e0   Haavard Skinnemoen   Add support for e...
36
  static struct spi_flash *env_flash;
afa81a775   Andreas Fenkart   env_sf: factor ou...
37
  static int setup_flash_device(void)
7319bcaf8   Wolfgang Wegner   add redundant env...
38
  {
19c31285a   Gong Qianyu   dm: env_sf: fix s...
39
40
  #ifdef CONFIG_DM_SPI_FLASH
  	struct udevice *new;
afa81a775   Andreas Fenkart   env_sf: factor ou...
41
  	int	ret;
19c31285a   Gong Qianyu   dm: env_sf: fix s...
42

96907c0fe   Vignesh R   dm: spi: Read def...
43
  	/* speed and mode will be read from DT */
19c31285a   Gong Qianyu   dm: env_sf: fix s...
44
  	ret = spi_flash_probe_bus_cs(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
25a17652c   Konstantin Porotchkin   fix: env: Fix the...
45
46
  				     CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE,
  				     &new);
19c31285a   Gong Qianyu   dm: env_sf: fix s...
47
  	if (ret) {
0ac7d722e   Simon Glass   env: Move get/set...
48
  		env_set_default("spi_flash_probe_bus_cs() failed", 0);
c59519919   Simon Glass   env: Adjust the l...
49
  		return ret;
19c31285a   Gong Qianyu   dm: env_sf: fix s...
50
51
52
53
  	}
  
  	env_flash = dev_get_uclass_priv(new);
  #else
7319bcaf8   Wolfgang Wegner   add redundant env...
54
55
  
  	if (!env_flash) {
a3110f01c   Stefano Babic   env_sf: updated t...
56
57
58
59
  		env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS,
  			CONFIG_ENV_SPI_CS,
  			CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
  		if (!env_flash) {
0ac7d722e   Simon Glass   env: Move get/set...
60
  			env_set_default("spi_flash_probe() failed", 0);
c59519919   Simon Glass   env: Adjust the l...
61
  			return -EIO;
a3110f01c   Stefano Babic   env_sf: updated t...
62
  		}
7319bcaf8   Wolfgang Wegner   add redundant env...
63
  	}
19c31285a   Gong Qianyu   dm: env_sf: fix s...
64
  #endif
afa81a775   Andreas Fenkart   env_sf: factor ou...
65
66
67
68
  	return 0;
  }
  
  #if defined(CONFIG_ENV_OFFSET_REDUND)
4415f1d1f   Simon Glass   env: Create a loc...
69
  #ifdef CMD_SAVEENV
e5bce247b   Simon Glass   env: Switch over ...
70
  static int env_sf_save(void)
afa81a775   Andreas Fenkart   env_sf: factor ou...
71
72
  {
  	env_t	env_new;
d3716dd64   Simon Glass   env: Rename the r...
73
  	char	*saved_buffer = NULL, flag = ENV_REDUND_OBSOLETE;
0b2e5bbe6   Andreas Fenkart   env_sf: use DIV_R...
74
  	u32	saved_size, saved_offset, sector;
afa81a775   Andreas Fenkart   env_sf: factor ou...
75
76
77
78
79
  	int	ret;
  
  	ret = setup_flash_device();
  	if (ret)
  		return ret;
7319bcaf8   Wolfgang Wegner   add redundant env...
80

7ce1526ed   Marek Vasut   env: Add env_expo...
81
82
  	ret = env_export(&env_new);
  	if (ret)
c59519919   Simon Glass   env: Adjust the l...
83
  		return -EIO;
d3716dd64   Simon Glass   env: Rename the r...
84
  	env_new.flags	= ENV_REDUND_ACTIVE;
ea882baf9   Wolfgang Denk   New implementatio...
85

203e94f6c   Simon Glass   env: Add an enum ...
86
  	if (gd->env_valid == ENV_VALID) {
a3110f01c   Stefano Babic   env_sf: updated t...
87
  		env_new_offset = CONFIG_ENV_OFFSET_REDUND;
9dca18a27   Ye Li   MLK-22279-1 env: ...
88
  		env_offset = env_get_offset(CONFIG_ENV_OFFSET);
a3110f01c   Stefano Babic   env_sf: updated t...
89
  	} else {
9dca18a27   Ye Li   MLK-22279-1 env: ...
90
  		env_new_offset = env_get_offset(CONFIG_ENV_OFFSET);
a3110f01c   Stefano Babic   env_sf: updated t...
91
92
  		env_offset = CONFIG_ENV_OFFSET_REDUND;
  	}
7319bcaf8   Wolfgang Wegner   add redundant env...
93
94
95
96
  	/* Is the sector larger than the env (i.e. embedded) */
  	if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
  		saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE;
  		saved_offset = env_new_offset + CONFIG_ENV_SIZE;
7dd017446   Ravi Babu   env: use cache li...
97
  		saved_buffer = memalign(ARCH_DMA_MINALIGN, saved_size);
7319bcaf8   Wolfgang Wegner   add redundant env...
98
  		if (!saved_buffer) {
c59519919   Simon Glass   env: Adjust the l...
99
  			ret = -ENOMEM;
7319bcaf8   Wolfgang Wegner   add redundant env...
100
101
  			goto done;
  		}
9ba5e5bc2   Heiko Schocher   Revert "env: add ...
102
103
  		ret = spi_flash_read(env_flash, saved_offset,
  					saved_size, saved_buffer);
7319bcaf8   Wolfgang Wegner   add redundant env...
104
105
106
  		if (ret)
  			goto done;
  	}
0b2e5bbe6   Andreas Fenkart   env_sf: use DIV_R...
107
  	sector = DIV_ROUND_UP(CONFIG_ENV_SIZE, CONFIG_ENV_SECT_SIZE);
7319bcaf8   Wolfgang Wegner   add redundant env...
108
109
110
111
112
113
114
115
  
  	puts("Erasing SPI flash...");
  	ret = spi_flash_erase(env_flash, env_new_offset,
  				sector * CONFIG_ENV_SECT_SIZE);
  	if (ret)
  		goto done;
  
  	puts("Writing to SPI flash...");
7319bcaf8   Wolfgang Wegner   add redundant env...
116

a3110f01c   Stefano Babic   env_sf: updated t...
117
  	ret = spi_flash_write(env_flash, env_new_offset,
cd0f4fa1c   Tom Rini   Revert "env: fix ...
118
  		CONFIG_ENV_SIZE, &env_new);
7319bcaf8   Wolfgang Wegner   add redundant env...
119
120
121
122
123
124
125
126
127
  	if (ret)
  		goto done;
  
  	if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
  		ret = spi_flash_write(env_flash, saved_offset,
  					saved_size, saved_buffer);
  		if (ret)
  			goto done;
  	}
eb58a7fc7   Igor Grinberg   env: clean env_sf...
128
  	ret = spi_flash_write(env_flash, env_offset + offsetof(env_t, flags),
cd0f4fa1c   Tom Rini   Revert "env: fix ...
129
  				sizeof(env_new.flags), &flag);
a3110f01c   Stefano Babic   env_sf: updated t...
130
131
  	if (ret)
  		goto done;
7319bcaf8   Wolfgang Wegner   add redundant env...
132

7319bcaf8   Wolfgang Wegner   add redundant env...
133
134
  	puts("done
  ");
203e94f6c   Simon Glass   env: Add an enum ...
135
  	gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND;
a3110f01c   Stefano Babic   env_sf: updated t...
136

2dc55d9ed   thomas.langer@lantiq.com   fix redundant env...
137
138
  	printf("Valid environment: %d
  ", (int)gd->env_valid);
a3110f01c   Stefano Babic   env_sf: updated t...
139

7319bcaf8   Wolfgang Wegner   add redundant env...
140
141
142
   done:
  	if (saved_buffer)
  		free(saved_buffer);
eb58a7fc7   Igor Grinberg   env: clean env_sf...
143

7319bcaf8   Wolfgang Wegner   add redundant env...
144
145
  	return ret;
  }
4415f1d1f   Simon Glass   env: Create a loc...
146
  #endif /* CMD_SAVEENV */
7319bcaf8   Wolfgang Wegner   add redundant env...
147

c59519919   Simon Glass   env: Adjust the l...
148
  static int env_sf_load(void)
7319bcaf8   Wolfgang Wegner   add redundant env...
149
150
  {
  	int ret;
80719938c   Simon Goldschmidt   env: sf: use env_...
151
152
  	int read1_fail, read2_fail;
  	env_t *tmp_env1, *tmp_env2;
7319bcaf8   Wolfgang Wegner   add redundant env...
153

7dd017446   Ravi Babu   env: use cache li...
154
155
156
157
  	tmp_env1 = (env_t *)memalign(ARCH_DMA_MINALIGN,
  			CONFIG_ENV_SIZE);
  	tmp_env2 = (env_t *)memalign(ARCH_DMA_MINALIGN,
  			CONFIG_ENV_SIZE);
ea882baf9   Wolfgang Denk   New implementatio...
158
  	if (!tmp_env1 || !tmp_env2) {
0ac7d722e   Simon Glass   env: Move get/set...
159
  		env_set_default("malloc() failed", 0);
c59519919   Simon Glass   env: Adjust the l...
160
  		ret = -EIO;
2dc55d9ed   thomas.langer@lantiq.com   fix redundant env...
161
  		goto out;
7319bcaf8   Wolfgang Wegner   add redundant env...
162
  	}
8fee8845e   Andreas Fenkart   enf_sf: reuse set...
163
164
  	ret = setup_flash_device();
  	if (ret)
2dc55d9ed   thomas.langer@lantiq.com   fix redundant env...
165
  		goto out;
7319bcaf8   Wolfgang Wegner   add redundant env...
166

9dca18a27   Ye Li   MLK-22279-1 env: ...
167
  	read1_fail = spi_flash_read(env_flash, env_get_offset(CONFIG_ENV_OFFSET),
9ba5e5bc2   Heiko Schocher   Revert "env: add ...
168
169
170
  				    CONFIG_ENV_SIZE, tmp_env1);
  	read2_fail = spi_flash_read(env_flash, CONFIG_ENV_OFFSET_REDUND,
  				    CONFIG_ENV_SIZE, tmp_env2);
ea882baf9   Wolfgang Denk   New implementatio...
171

80719938c   Simon Goldschmidt   env: sf: use env_...
172
173
  	ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
  				read2_fail);
7319bcaf8   Wolfgang Wegner   add redundant env...
174

7319bcaf8   Wolfgang Wegner   add redundant env...
175
176
  	spi_flash_free(env_flash);
  	env_flash = NULL;
7319bcaf8   Wolfgang Wegner   add redundant env...
177
  out:
ea882baf9   Wolfgang Denk   New implementatio...
178
179
  	free(tmp_env1);
  	free(tmp_env2);
c59519919   Simon Glass   env: Adjust the l...
180
181
  
  	return ret;
7319bcaf8   Wolfgang Wegner   add redundant env...
182
183
  }
  #else
4415f1d1f   Simon Glass   env: Create a loc...
184
  #ifdef CMD_SAVEENV
e5bce247b   Simon Glass   env: Switch over ...
185
  static int env_sf_save(void)
8c66497e0   Haavard Skinnemoen   Add support for e...
186
  {
0b2e5bbe6   Andreas Fenkart   env_sf: use DIV_R...
187
  	u32	saved_size, saved_offset, sector;
7ce1526ed   Marek Vasut   env: Add env_expo...
188
  	char	*saved_buffer = NULL;
eb58a7fc7   Igor Grinberg   env: clean env_sf...
189
  	int	ret = 1;
cd0f4fa1c   Tom Rini   Revert "env: fix ...
190
  	env_t	env_new;
19c31285a   Gong Qianyu   dm: env_sf: fix s...
191

afa81a775   Andreas Fenkart   env_sf: factor ou...
192
193
194
  	ret = setup_flash_device();
  	if (ret)
  		return ret;
8c66497e0   Haavard Skinnemoen   Add support for e...
195

5b3375ac8   Mike Frysinger   env_sf: support e...
196
197
198
  	/* Is the sector larger than the env (i.e. embedded) */
  	if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
  		saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE;
9dca18a27   Ye Li   MLK-22279-1 env: ...
199
  		saved_offset = env_get_offset(CONFIG_ENV_OFFSET) + CONFIG_ENV_SIZE;
5b3375ac8   Mike Frysinger   env_sf: support e...
200
  		saved_buffer = malloc(saved_size);
eb58a7fc7   Igor Grinberg   env: clean env_sf...
201
  		if (!saved_buffer)
5b3375ac8   Mike Frysinger   env_sf: support e...
202
  			goto done;
eb58a7fc7   Igor Grinberg   env: clean env_sf...
203

9ba5e5bc2   Heiko Schocher   Revert "env: add ...
204
205
  		ret = spi_flash_read(env_flash, saved_offset,
  			saved_size, saved_buffer);
5b3375ac8   Mike Frysinger   env_sf: support e...
206
207
208
  		if (ret)
  			goto done;
  	}
7ce1526ed   Marek Vasut   env: Add env_expo...
209
210
  	ret = env_export(&env_new);
  	if (ret)
a3110f01c   Stefano Babic   env_sf: updated t...
211
  		goto done;
a3110f01c   Stefano Babic   env_sf: updated t...
212

0b2e5bbe6   Andreas Fenkart   env_sf: use DIV_R...
213
  	sector = DIV_ROUND_UP(CONFIG_ENV_SIZE, CONFIG_ENV_SECT_SIZE);
8c66497e0   Haavard Skinnemoen   Add support for e...
214
  	puts("Erasing SPI flash...");
9dca18a27   Ye Li   MLK-22279-1 env: ...
215
  	ret = spi_flash_erase(env_flash, env_get_offset(CONFIG_ENV_OFFSET),
a3110f01c   Stefano Babic   env_sf: updated t...
216
  		sector * CONFIG_ENV_SECT_SIZE);
5b3375ac8   Mike Frysinger   env_sf: support e...
217
218
  	if (ret)
  		goto done;
8c66497e0   Haavard Skinnemoen   Add support for e...
219
220
  
  	puts("Writing to SPI flash...");
9dca18a27   Ye Li   MLK-22279-1 env: ...
221
  	ret = spi_flash_write(env_flash, env_get_offset(CONFIG_ENV_OFFSET),
cd0f4fa1c   Tom Rini   Revert "env: fix ...
222
  		CONFIG_ENV_SIZE, &env_new);
5b3375ac8   Mike Frysinger   env_sf: support e...
223
224
  	if (ret)
  		goto done;
8c66497e0   Haavard Skinnemoen   Add support for e...
225

5b3375ac8   Mike Frysinger   env_sf: support e...
226
  	if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) {
a3110f01c   Stefano Babic   env_sf: updated t...
227
228
  		ret = spi_flash_write(env_flash, saved_offset,
  			saved_size, saved_buffer);
5b3375ac8   Mike Frysinger   env_sf: support e...
229
230
231
232
233
  		if (ret)
  			goto done;
  	}
  
  	ret = 0;
8c66497e0   Haavard Skinnemoen   Add support for e...
234
235
  	puts("done
  ");
5b3375ac8   Mike Frysinger   env_sf: support e...
236
237
238
239
  
   done:
  	if (saved_buffer)
  		free(saved_buffer);
eb58a7fc7   Igor Grinberg   env: clean env_sf...
240

5b3375ac8   Mike Frysinger   env_sf: support e...
241
  	return ret;
8c66497e0   Haavard Skinnemoen   Add support for e...
242
  }
4415f1d1f   Simon Glass   env: Create a loc...
243
  #endif /* CMD_SAVEENV */
8c66497e0   Haavard Skinnemoen   Add support for e...
244

c59519919   Simon Glass   env: Adjust the l...
245
  static int env_sf_load(void)
8c66497e0   Haavard Skinnemoen   Add support for e...
246
247
  {
  	int ret;
5a89fa927   Ying Zhang   SPL: P2020RDB: fi...
248
  	char *buf = NULL;
8c66497e0   Haavard Skinnemoen   Add support for e...
249

7dd017446   Ravi Babu   env: use cache li...
250
  	buf = (char *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE);
c041c60c6   Andreas Fenkart   env_sf: re-order ...
251
  	if (!buf) {
0ac7d722e   Simon Glass   env: Move get/set...
252
  		env_set_default("malloc() failed", 0);
c59519919   Simon Glass   env: Adjust the l...
253
  		return -EIO;
ea882baf9   Wolfgang Denk   New implementatio...
254
  	}
8c66497e0   Haavard Skinnemoen   Add support for e...
255

c041c60c6   Andreas Fenkart   env_sf: re-order ...
256
257
258
  	ret = setup_flash_device();
  	if (ret)
  		goto out;
9ba5e5bc2   Heiko Schocher   Revert "env: add ...
259
  	ret = spi_flash_read(env_flash,
9dca18a27   Ye Li   MLK-22279-1 env: ...
260
  		env_get_offset(CONFIG_ENV_OFFSET), CONFIG_ENV_SIZE, buf);
ea882baf9   Wolfgang Denk   New implementatio...
261
  	if (ret) {
0ac7d722e   Simon Glass   env: Move get/set...
262
  		env_set_default("spi_flash_read() failed", 0);
c041c60c6   Andreas Fenkart   env_sf: re-order ...
263
  		goto err_read;
ea882baf9   Wolfgang Denk   New implementatio...
264
  	}
8c66497e0   Haavard Skinnemoen   Add support for e...
265

ea882baf9   Wolfgang Denk   New implementatio...
266
  	ret = env_import(buf, 1);
42a1820bb   Simon Goldschmidt   env: make env_imp...
267
  	if (!ret)
203e94f6c   Simon Glass   env: Add an enum ...
268
  		gd->env_valid = ENV_VALID;
c041c60c6   Andreas Fenkart   env_sf: re-order ...
269
270
  
  err_read:
8c66497e0   Haavard Skinnemoen   Add support for e...
271
272
  	spi_flash_free(env_flash);
  	env_flash = NULL;
c041c60c6   Andreas Fenkart   env_sf: re-order ...
273
274
  out:
  	free(buf);
c59519919   Simon Glass   env: Adjust the l...
275
276
  
  	return ret;
8c66497e0   Haavard Skinnemoen   Add support for e...
277
  }
7319bcaf8   Wolfgang Wegner   add redundant env...
278
  #endif
8c66497e0   Haavard Skinnemoen   Add support for e...
279

a09fea1d2   Tom Rini   env: Finish migra...
280
  #if CONFIG_ENV_ADDR != 0x0
119c01c2a   Rajesh Bhagat   env: sf: define A...
281
282
283
284
285
  __weak void *env_sf_get_env_addr(void)
  {
  	return (void *)CONFIG_ENV_ADDR;
  }
  #endif
a09fea1d2   Tom Rini   env: Finish migra...
286
  #if defined(INITENV) && (CONFIG_ENV_ADDR != 0x0)
b500c92b7   Ashish Kumar   env: sf: Add supp...
287
288
  static int env_sf_init(void)
  {
119c01c2a   Rajesh Bhagat   env: sf: define A...
289
  	env_t *env_ptr = (env_t *)env_sf_get_env_addr();
b500c92b7   Ashish Kumar   env: sf: Add supp...
290
291
292
293
294
295
296
297
298
299
300
301
  
  	if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
  		gd->env_addr	= (ulong)&(env_ptr->data);
  		gd->env_valid	= 1;
  	} else {
  		gd->env_addr = (ulong)&default_environment[0];
  		gd->env_valid = 1;
  	}
  
  	return 0;
  }
  #endif
4415f1d1f   Simon Glass   env: Create a loc...
302
303
  U_BOOT_ENV_LOCATION(sf) = {
  	.location	= ENVL_SPI_FLASH,
ac358beb8   Simon Glass   env: Drop the env...
304
  	ENV_NAME("SPI Flash")
e5bce247b   Simon Glass   env: Switch over ...
305
  	.load		= env_sf_load,
4415f1d1f   Simon Glass   env: Create a loc...
306
  #ifdef CMD_SAVEENV
e5bce247b   Simon Glass   env: Switch over ...
307
  	.save		= env_save_ptr(env_sf_save),
4415f1d1f   Simon Glass   env: Create a loc...
308
  #endif
a09fea1d2   Tom Rini   env: Finish migra...
309
  #if defined(INITENV) && (CONFIG_ENV_ADDR != 0x0)
b500c92b7   Ashish Kumar   env: sf: Add supp...
310
311
  	.init		= env_sf_init,
  #endif
4415f1d1f   Simon Glass   env: Create a loc...
312
  };