]> git.ipfire.org Git - thirdparty/u-boot.git/blame - env/onenand.c
fdt: fix fdtdec_setup_memory_banksize()
[thirdparty/u-boot.git] / env / onenand.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
d7e8ce10 2/*
ea882baf
WD
3 * (C) Copyright 2010 DENX Software Engineering
4 * Wolfgang Denk <wd@denx.de>
5 *
937076f8 6 * (C) Copyright 2005-2009 Samsung Electronics
d7e8ce10 7 * Kyungmin Park <kyungmin.park@samsung.com>
d7e8ce10
KP
8 */
9
10#include <common.h>
d7e8ce10
KP
11#include <command.h>
12#include <environment.h>
13#include <linux/stddef.h>
14#include <malloc.h>
ea882baf
WD
15#include <search.h>
16#include <errno.h>
b919ec25 17#include <onenand_uboot.h>
d7e8ce10 18
7b15e2bb 19#include <linux/compat.h>
d7e8ce10
KP
20#include <linux/mtd/mtd.h>
21#include <linux/mtd/onenand.h>
22
034afbcc 23#define ONENAND_MAX_ENV_SIZE CONFIG_ENV_SIZE
937076f8
KP
24#define ONENAND_ENV_SIZE(mtd) (ONENAND_MAX_ENV_SIZE - ENV_HEADER_SIZE)
25
a9da2b41
KP
26DECLARE_GLOBAL_DATA_PTR;
27
c5951991 28static int env_onenand_load(void)
d7e8ce10 29{
937076f8 30 struct mtd_info *mtd = &onenand_mtd;
b821cead 31#ifdef CONFIG_ENV_ADDR_FLEX
c758e947 32 struct onenand_chip *this = &onenand_chip;
b821cead 33#endif
ea882baf 34 int rc;
2ae64f51 35 size_t retlen;
ea882baf 36#ifdef ENV_IS_EMBEDDED
994bc671 37 char *buf = (char *)&environment;
ea882baf
WD
38#else
39 loff_t env_addr = CONFIG_ENV_ADDR;
cd0f4fa1
TR
40 char onenand_env[ONENAND_MAX_ENV_SIZE];
41 char *buf = (char *)&onenand_env[0];
ea882baf 42#endif /* ENV_IS_EMBEDDED */
d7e8ce10 43
ea882baf
WD
44#ifndef ENV_IS_EMBEDDED
45# ifdef CONFIG_ENV_ADDR_FLEX
c758e947
AKS
46 if (FLEXONENAND(this))
47 env_addr = CONFIG_ENV_ADDR_FLEX;
ea882baf 48# endif
d7e8ce10 49 /* Check OneNAND exist */
937076f8 50 if (mtd->writesize)
d7e8ce10 51 /* Ignore read fail */
dfe64e2c 52 mtd_read(mtd, env_addr, ONENAND_MAX_ENV_SIZE,
b919ec25 53 &retlen, (u_char *)buf);
d7e8ce10 54 else
937076f8 55 mtd->writesize = MAX_ONENAND_PAGESIZE;
ea882baf 56#endif /* !ENV_IS_EMBEDDED */
d7e8ce10 57
ea882baf 58 rc = env_import(buf, 1);
42a1820b 59 if (!rc)
203e94f6 60 gd->env_valid = ENV_VALID;
c5951991 61
42a1820b 62 return rc;
d7e8ce10
KP
63}
64
e5bce247 65static int env_onenand_save(void)
d7e8ce10 66{
cd0f4fa1 67 env_t env_new;
7ce1526e 68 int ret;
937076f8 69 struct mtd_info *mtd = &onenand_mtd;
b821cead 70#ifdef CONFIG_ENV_ADDR_FLEX
c758e947 71 struct onenand_chip *this = &onenand_chip;
b821cead 72#endif
ea882baf
WD
73 loff_t env_addr = CONFIG_ENV_ADDR;
74 size_t retlen;
a9da2b41
KP
75 struct erase_info instr = {
76 .callback = NULL,
77 };
ea882baf 78
7ce1526e
MV
79 ret = env_export(&env_new);
80 if (ret)
81 return ret;
d7e8ce10 82
0e8d1586 83 instr.len = CONFIG_ENV_SIZE;
b821cead 84#ifdef CONFIG_ENV_ADDR_FLEX
c758e947
AKS
85 if (FLEXONENAND(this)) {
86 env_addr = CONFIG_ENV_ADDR_FLEX;
87 instr.len = CONFIG_ENV_SIZE_FLEX;
88 instr.len <<= onenand_mtd.eraseregions[0].numblocks == 1 ?
89 1 : 0;
90 }
b821cead 91#endif
d7e8ce10 92 instr.addr = env_addr;
937076f8 93 instr.mtd = mtd;
dfe64e2c 94 if (mtd_erase(mtd, &instr)) {
48287792 95 printf("OneNAND: erase failed at 0x%08llx\n", env_addr);
d7e8ce10
KP
96 return 1;
97 }
98
dfe64e2c 99 if (mtd_write(mtd, env_addr, ONENAND_MAX_ENV_SIZE, &retlen,
cd0f4fa1 100 (u_char *)&env_new)) {
8d2effea 101 printf("OneNAND: write failed at 0x%llx\n", instr.addr);
d7e8ce10
KP
102 return 2;
103 }
104
105 return 0;
106}
107
4415f1d1
SG
108U_BOOT_ENV_LOCATION(onenand) = {
109 .location = ENVL_ONENAND,
ac358beb 110 ENV_NAME("OneNAND")
e5bce247
SG
111 .load = env_onenand_load,
112 .save = env_save_ptr(env_onenand_save),
4415f1d1 113};