blob: 7cf5ba16c0721f3256355d595a16c5276bd0ea4e [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001#include <nand.h>
2#include <spi_flash.h>
3#include <common.h>
4#include <linux/types.h>
5#include <linux/mtd/mtd.h>
6#include <linux/mtd/nand.h>
7#include <linux/mtd/partitions.h>
8#include <asm/errno.h>
9#include <asm/string.h>
10#include <mtd/pxa3xx_bbm.h>
11#include <asm/arch/pxa3xx_nand.h>
12
13int nand_curr_device = -1;
14#ifdef CONFIG_CMD_NAND
15nand_info_t nand_info[CONFIG_SYS_MAX_NAND_DEVICE];
16#endif
17#ifdef CONFIG_CMD_ONENAND
18extern struct mtd_info onenand_mtd;
19#endif
20
21#ifdef CONFIG_NAND_PXA
22
23#ifdef MEP_OTA_FLASH_ADDRESS
24void nand_lock_priv_block(void)
25{
26 int chip = nand_curr_device;
27
28 if (chip < 0)
29 return;
30
31 nand_info[chip].protect_enabled = 1;
32}
33
34void nand_unlock_priv_block(void)
35{
36 int chip = nand_curr_device;
37
38 if (chip < 0)
39 return;
40
41 nand_info[chip].protect_enabled = 0;
42}
43
44static void nand_init_proctect_block(nand_info_t *nand)
45{
46 nand->protect_enabled = 1;
47 nand->protect_start = MEP_OTA_FLASH_ADDRESS;
48 nand->protect_end = MEP_OTA_FLASH_ADDRESS + MEP_OTA_FLASH_LEN;
49}
50#endif
51
52void nand_init()
53{
54 struct pxa3xx_nand_platform_data pxa_nandinfo;
55 struct pxa3xx_nand *nand;
56 int chip;
57
58 pxa_nandinfo.mmio_base = CONFIG_SYS_NAND_BASE;
59 pxa_nandinfo.enable_arbiter = 1;
60 pxa_nandinfo.RD_CNT_DEL = 0;
61
62 nand = pxa3xx_nand_probe(&pxa_nandinfo);
63 if (!nand) {
64 printf("pxa3xx-nand probe failed!!\n");
65 return;
66 }
67
68 for (chip = 0; chip < CONFIG_SYS_MAX_NAND_DEVICE; chip ++) {
69 if (nand->mtd[chip]) {
70#ifdef MEP_OTA_FLASH_ADDRESS
71 nand_init_proctect_block(nand->mtd[chip]);
72#endif
73 memcpy(&(nand_info[chip]), nand->mtd[chip], sizeof(struct mtd_info));
74
75 if (nand_curr_device < 0)
76 nand_curr_device = chip;
77 }
78 }
79
80 if (nand_curr_device < 0)
81 printf("No NAND dev is found !!!\n\n");
82}
83#endif
84
85#ifdef CONFIG_SPI_COPYBACK_NAND
86#define BACK_NTIM_OF 0x1000
87#define BACK_OBM_OF 0x30000
88#define BACK_UBOOT_OF 0x40000
89#define BACK_ZIMAGE_OF 0x100000
90#define BURN_ZIMAGE_OF 0x400000
91#define MAX_NTIM_SIZE 0x1000
92#define MAX_OBM_SIZE 0xf000
93#define MAX_UBOOT_SIZE 0x30000
94#define MAX_ZIMAGE_SIZE 0x300000
95#define NTIM_HEADER_1 0x30102
96#define NTIM_HEADER_2 0x54494d48
97#define BBT_INIT_COMMAND "bbt init nand new"
98int nand_update_callback(void)
99{
100 void *buf = (void *)0x500000;
101 size_t retlen;
102 int ret;
103 unsigned int header_1, header_2;
104 struct mtd_info *mtd;
105
106 if (nand_curr_device != 0)
107 return -1;
108
109 mtd = &nand_info[0];
110 mtd->read(mtd, 0, mtd->writesize, &retlen, buf);
111 header_1 = *(unsigned int*)buf;
112 header_2 = *((unsigned int*)buf + 1);
113 if (header_1 == NTIM_HEADER_1 && header_2 == NTIM_HEADER_2) {
114 return 1;
115 }
116 else {
117 extern int not_updating;
118 extern struct spi_flash *flash;
119 struct erase_info instr = {
120 .callback = NULL,
121 };
122
123 printf("\n### begin to update nand from spi nor ###\n");
124 run_command("nand device 1", 0);
125 not_updating = 1;
126 run_command(BBT_INIT_COMMAND, 0);
127 run_command("nand device 0", 0);
128 not_updating = 0;
129 run_command(BBT_INIT_COMMAND, 0);
130 not_updating = 1;
131 instr.addr = mtd->erasesize;
132 instr.len = instr.addr * 3;
133 printf("\nerasing..");
134 ret = mtd->erase(mtd, &instr);
135 if (ret) {
136 printf("erase 1-3 block failed!!!\n");
137 goto UPDATE_FAILED;
138 }
139
140 instr.addr = BACK_ZIMAGE_OF;
141 instr.len = MAX_ZIMAGE_SIZE * 2;
142 ret = mtd->erase(mtd, &instr);
143 if (ret) {
144 printf("erase 0x100000-0x700000 failed!!!\n");
145 goto UPDATE_FAILED;
146 }
147
148 printf("spi read 1..");
149 ret = spi_flash_read(flash, BACK_NTIM_OF, MAX_NTIM_SIZE, buf);
150 if (ret) {
151 printf("read ntim failed\n");
152 goto UPDATE_FAILED;
153 }
154
155 printf("2..");
156 buf += MAX_NTIM_SIZE;
157 ret = spi_flash_read(flash, BACK_OBM_OF, MAX_OBM_SIZE, buf);
158 if (ret) {
159 printf("read obm failed\n");
160 goto UPDATE_FAILED;
161 }
162
163 printf("3..");
164 buf += MAX_OBM_SIZE;
165 ret = spi_flash_read(flash, BACK_UBOOT_OF, MAX_UBOOT_SIZE,
166 buf);
167 if (ret) {
168 printf("read uboot failed\n");
169 goto UPDATE_FAILED;
170 }
171
172 printf("4..");
173 buf += MAX_UBOOT_SIZE;
174 ret = spi_flash_read(flash, BACK_ZIMAGE_OF, MAX_ZIMAGE_SIZE,
175 buf);
176 if (ret) {
177 printf("read zImage failed\n");
178 goto UPDATE_FAILED;
179 }
180
181 printf("nand write 1..");
182 buf = (void *)0x500000;
183 ret = mtd->write(mtd, 0, MAX_NTIM_SIZE, &retlen, buf);
184 if (ret) {
185 printf("update ntim failed!!\n");
186 goto UPDATE_FAILED;
187 }
188
189 printf("2..");
190 buf += MAX_NTIM_SIZE;
191 ret = mtd->write(mtd, mtd->erasesize, MAX_OBM_SIZE, &retlen,
192 buf);
193 if (ret) {
194 printf("update obm failed!!\n");
195 goto UPDATE_FAILED;
196 }
197
198 printf("3..");
199 buf += MAX_OBM_SIZE;
200 ret = mtd->write(mtd, mtd->erasesize * 2, MAX_UBOOT_SIZE,
201 &retlen, buf);
202 if (ret) {
203 printf("update uboot failed!!\n");
204 goto UPDATE_FAILED;
205 }
206
207 printf("4..");
208 buf += MAX_UBOOT_SIZE;
209 ret = mtd->write(mtd, BURN_ZIMAGE_OF, MAX_ZIMAGE_SIZE,
210 &retlen, buf);
211 if (ret) {
212 printf("update zImage failed!!\n");
213 goto UPDATE_FAILED;
214 }
215
216 printf("update done!!\n");
217 return 0;
218UPDATE_FAILED:
219
220 printf("!!!update failed!!!\n");
221 return -1;
222 }
223}
224#endif