blob: 7c34949a9f447713689571d79b97e4963a073671 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*
2 * (C) Copyright 2016 ZXIC Inc.
3 */
4
5
6#include <common.h>
7#include <asm/io.h>
8#include <bbt.h>
9#include "config.h"
10#include "flash.h"
11
12
13static uint8_t block_bad_table[BBT_SIZE]={0};
14
15
16static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
17static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
18
19static struct nand_bbt_descr bbt_main_descr = {
20 .offs = 4,
21 .len = 4,
22 .veroffs = 20,
23 .maxblocks = 16,
24 .pattern = bbt_pattern,
25};
26
27static struct nand_bbt_descr bbt_mirror_descr = {
28 .offs = 4,
29 .len = 4,
30 .veroffs = 20,
31 .maxblocks = 16,
32 .pattern = mirror_pattern,
33};
34
35static int nand_check_pattern(uint8_t *buf,struct nand_bbt_descr *td)
36{
37 int i;
38 uint8_t *p = buf;
39 p += td->offs;
40
41 /* Compare the pattern */
42 for (i = 0; i < td->len; i++)
43 {
44 if (p[i] != td->pattern[i])
45 return -1;
46 }
47
48 return 0;
49}
50
51void nand_creat_ram_bbt( void )
52{
53 uint32_t i = 0;
54 uint32_t off = 0;
55 uint32_t oob_size = flash.oob_size;
56 uint32_t block_size = flash.block_size;
57 uint8_t oob[256]; /* ÕâÀﶨÒå×î´óµÄOOB SIZE */
58#ifdef CONFIG_ZX297520V3E_MDL_AB
59 uint32_t block_nums = 72;
60#else
61 uint32_t block_nums = 17;
62#endif
63
64 for( i=0; i<block_nums; i++ )
65 {
66 flash.read_oob(&oob[0], off, oob_size);
67 if(oob[0] != 0xff) /* bad block */
68 block_bad_table[i] = BAD_BLOCK;
69 else
70 block_bad_table[i] = 0x0;
71
72 off += block_size;
73 }
74}
75
76
77int nand_search_bbt(struct nand_bbt_descr *td)
78{
79
80 int startblock, block;
81 int blocktopage = flash.block_size_shift - flash.page_size_shift;
82
83 uint8_t oob_buffer[256]={0xFF};
84 uint32_t offs = 0;
85
86 /* Search direction down -> top */
87 startblock = flash.block_num -1;
88
89 td->page= -1;
90 /* Scan the maximum number of blocks */
91 for (block = 0; block < td->maxblocks; block++)
92 {
93
94 int actblock = startblock -block;
95 offs = actblock << flash.block_size_shift;
96
97 /* Read first page */
98 flash.read_oob(oob_buffer, offs, flash.oob_size);
99 if (!nand_check_pattern(oob_buffer,td))
100 {
101 td->page = actblock << blocktopage;
102 td->version= oob_buffer[td->veroffs];
103
104 break;
105 }
106 }
107
108 return 0;
109}
110
111
112static int nand_read_bbt(struct nand_bbt_descr *td,int num)
113{
114 int bits=2;
115
116 int res, i, j, act = 0;
117 int totlen;
118 int from;
119 uint8_t msk = (uint8_t) ((1 << bits) - 1);
120 totlen = (num * bits) >> 3;
121 from =(td->page)<<(flash.page_size_shift);
122 char* buf;
123
124
125 res = flash.read_page_raw(CFG_TEMP_ADDR, from);
126 if (res < 0)
127 {
128 return -1;
129 }
130
131 buf =(char*) CFG_TEMP_ADDR;
132
133
134 /* Analyse data */
135 for (i = 0; i < totlen; i++)
136 {
137 uint8_t dat = buf[i];
138 for (j = 0; j < 8; j += bits, act += 2)
139 {
140 uint8_t tmp = (dat >> j) & msk;
141 if (tmp == msk)
142 {
143 block_bad_table[(act >> 1)]= 0X0;
144 continue;
145 }
146 else
147 {
148 block_bad_table[(act >> 1)]= BAD_BLOCK;
149 }
150 }
151 }
152
153 return 0;
154}
155
156
157static void nand_init_bbt_descr(struct nand_bbt_descr *td,
158 struct nand_bbt_descr *md)
159{
160 switch(flash.manuf_id)
161 {
162 case NAND_MFR_PARAGON:
163 if(flash.device_id != NAND_DEVID_FDANWEI_1G)
164 {
165 td->offs = BBT_INFO_OOB_OFFSET_PARAGON;
166 md->offs = BBT_INFO_OOB_OFFSET_PARAGON;
167 td->veroffs = BBT_INFO_OOB_VER_OFFSET_PARAGON;
168 md->veroffs = BBT_INFO_OOB_VER_OFFSET_PARAGON;
169 }
170 break;
171 case NAND_MFR_HEYANGTEK:
172 td->offs = BBT_INFO_OOB_OFFSET_HEYANGTEK;
173 md->offs = BBT_INFO_OOB_OFFSET_HEYANGTEK;
174 td->veroffs = BBT_INFO_OOB_VER_OFFSET_HEYANGTEK;
175 md->veroffs =BBT_INFO_OOB_VER_OFFSET_HEYANGTEK;
176 break;
177 default:
178 break;
179 }
180}
181
182int nand_creat_bbt( void )
183{
184 struct nand_bbt_descr *td = &bbt_main_descr;
185 struct nand_bbt_descr *md = &bbt_mirror_descr;
186
187 nand_init_bbt_descr(td, md);
188
189 // 2.0 search main bbt
190 nand_search_bbt(td);
191 // 2.1 search mirror bbt
192 nand_search_bbt(md);
193
194 if(td->page==-1&&md->page ==-1)
195 {
196 /* if failed found bbt, we create a ram bbt */
197 nand_creat_ram_bbt();
198 return 0;
199 }
200
201 // 3.0 read and analyze bbt
202 if(td->page==-1)
203 {
204 nand_read_bbt(md,BBT_SIZE);
205 }
206 else
207 {
208 if(md->page == -1)
209 {
210 nand_read_bbt(td,BBT_SIZE);
211 }
212 else
213 {
214 if(td->version >= md->version)
215 {
216 nand_read_bbt(td,BBT_SIZE);
217 }
218 else
219 {
220 nand_read_bbt(md,BBT_SIZE);
221 }
222 }
223 }
224 printf("bbt ok.\n");
225
226 return 0;
227}
228
229/*******************************************************************************
230 * Function:
231 * Description:
232 * Parameters:
233 * Input:
234 *
235 * Output:
236 *
237 * Returns:
238 *
239 *
240 * Others:
241 ********************************************************************************/
242uint32_t nand_block_isbad(uint32_t offset)
243{
244 uint32_t block_offset = offset >> (flash.block_size_shift);
245 return block_bad_table[block_offset];
246}
247
248
249