Blame view
common/env_onenand.c
2.4 KB
d7e8ce101
|
1 |
/* |
ea882baf9
|
2 3 4 |
* (C) Copyright 2010 DENX Software Engineering * Wolfgang Denk <wd@denx.de> * |
937076f84
|
5 |
* (C) Copyright 2005-2009 Samsung Electronics |
d7e8ce101
|
6 7 |
* Kyungmin Park <kyungmin.park@samsung.com> * |
1a4596601
|
8 |
* SPDX-License-Identifier: GPL-2.0+ |
d7e8ce101
|
9 10 11 |
*/ #include <common.h> |
d7e8ce101
|
12 13 14 15 |
#include <command.h> #include <environment.h> #include <linux/stddef.h> #include <malloc.h> |
ea882baf9
|
16 17 |
#include <search.h> #include <errno.h> |
b919ec25e
|
18 |
#include <onenand_uboot.h> |
d7e8ce101
|
19 |
|
7b15e2bb9
|
20 |
#include <linux/compat.h> |
d7e8ce101
|
21 22 |
#include <linux/mtd/mtd.h> #include <linux/mtd/onenand.h> |
d7e8ce101
|
23 |
char *env_name_spec = "OneNAND"; |
034afbcc1
|
24 |
#define ONENAND_MAX_ENV_SIZE CONFIG_ENV_SIZE |
937076f84
|
25 |
#define ONENAND_ENV_SIZE(mtd) (ONENAND_MAX_ENV_SIZE - ENV_HEADER_SIZE) |
a9da2b410
|
26 |
DECLARE_GLOBAL_DATA_PTR; |
d7e8ce101
|
27 28 |
void env_relocate_spec(void) { |
937076f84
|
29 |
struct mtd_info *mtd = &onenand_mtd; |
b821cead7
|
30 |
#ifdef CONFIG_ENV_ADDR_FLEX |
c758e947a
|
31 |
struct onenand_chip *this = &onenand_chip; |
b821cead7
|
32 |
#endif |
ea882baf9
|
33 |
int rc; |
2ae64f513
|
34 |
size_t retlen; |
ea882baf9
|
35 |
#ifdef ENV_IS_EMBEDDED |
994bc671c
|
36 |
char *buf = (char *)&environment; |
ea882baf9
|
37 38 |
#else loff_t env_addr = CONFIG_ENV_ADDR; |
cd0f4fa1c
|
39 40 |
char onenand_env[ONENAND_MAX_ENV_SIZE]; char *buf = (char *)&onenand_env[0]; |
ea882baf9
|
41 |
#endif /* ENV_IS_EMBEDDED */ |
d7e8ce101
|
42 |
|
ea882baf9
|
43 44 |
#ifndef ENV_IS_EMBEDDED # ifdef CONFIG_ENV_ADDR_FLEX |
c758e947a
|
45 46 |
if (FLEXONENAND(this)) env_addr = CONFIG_ENV_ADDR_FLEX; |
ea882baf9
|
47 |
# endif |
d7e8ce101
|
48 |
/* Check OneNAND exist */ |
937076f84
|
49 |
if (mtd->writesize) |
d7e8ce101
|
50 |
/* Ignore read fail */ |
dfe64e2c8
|
51 |
mtd_read(mtd, env_addr, ONENAND_MAX_ENV_SIZE, |
b919ec25e
|
52 |
&retlen, (u_char *)buf); |
d7e8ce101
|
53 |
else |
937076f84
|
54 |
mtd->writesize = MAX_ONENAND_PAGESIZE; |
ea882baf9
|
55 |
#endif /* !ENV_IS_EMBEDDED */ |
d7e8ce101
|
56 |
|
ea882baf9
|
57 58 59 |
rc = env_import(buf, 1); if (rc) gd->env_valid = 1; |
d7e8ce101
|
60 61 62 63 |
} int saveenv(void) { |
cd0f4fa1c
|
64 |
env_t env_new; |
7ce1526ed
|
65 |
int ret; |
937076f84
|
66 |
struct mtd_info *mtd = &onenand_mtd; |
b821cead7
|
67 |
#ifdef CONFIG_ENV_ADDR_FLEX |
c758e947a
|
68 |
struct onenand_chip *this = &onenand_chip; |
b821cead7
|
69 |
#endif |
ea882baf9
|
70 71 |
loff_t env_addr = CONFIG_ENV_ADDR; size_t retlen; |
a9da2b410
|
72 73 74 |
struct erase_info instr = { .callback = NULL, }; |
ea882baf9
|
75 |
|
7ce1526ed
|
76 77 78 |
ret = env_export(&env_new); if (ret) return ret; |
d7e8ce101
|
79 |
|
0e8d15866
|
80 |
instr.len = CONFIG_ENV_SIZE; |
b821cead7
|
81 |
#ifdef CONFIG_ENV_ADDR_FLEX |
c758e947a
|
82 83 84 85 86 87 |
if (FLEXONENAND(this)) { env_addr = CONFIG_ENV_ADDR_FLEX; instr.len = CONFIG_ENV_SIZE_FLEX; instr.len <<= onenand_mtd.eraseregions[0].numblocks == 1 ? 1 : 0; } |
b821cead7
|
88 |
#endif |
d7e8ce101
|
89 |
instr.addr = env_addr; |
937076f84
|
90 |
instr.mtd = mtd; |
dfe64e2c8
|
91 |
if (mtd_erase(mtd, &instr)) { |
482877923
|
92 93 |
printf("OneNAND: erase failed at 0x%08llx ", env_addr); |
d7e8ce101
|
94 95 |
return 1; } |
dfe64e2c8
|
96 |
if (mtd_write(mtd, env_addr, ONENAND_MAX_ENV_SIZE, &retlen, |
cd0f4fa1c
|
97 |
(u_char *)&env_new)) { |
8d2effea2
|
98 99 |
printf("OneNAND: write failed at 0x%llx ", instr.addr); |
d7e8ce101
|
100 101 102 103 104 105 106 107 |
return 2; } return 0; } int env_init(void) { |
d7e8ce101
|
108 |
/* use default */ |
b919ec25e
|
109 |
gd->env_addr = (ulong)&default_environment[0]; |
d7e8ce101
|
110 111 112 113 |
gd->env_valid = 1; return 0; } |