blob: bf4626674fb88663f109671d107060283ea5f2b6 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -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#if defined(CONFIG_ZX297520V3E_MDL_AB) || defined(CONFIG_ZX297520V3E_VEHICLE_DC)
60 uint32_t block_nums = 72;
61#else
62 uint32_t block_nums = 17;
63#endif
64
65 for( i=0; i<block_nums; i++ )
66 {
67 flash.read_oob(&oob[0], off, oob_size);
68 if(oob[0] != 0xff) /* bad block */
69 block_bad_table[i] = BAD_BLOCK;
70 else
71 block_bad_table[i] = 0x0;
72
73 off += block_size;
74 }
75}
76
77
78int nand_search_bbt(struct nand_bbt_descr *td)
79{
80
81 int startblock, block;
82 int blocktopage = flash.block_size_shift - flash.page_size_shift;
83
84 uint8_t oob_buffer[256]={0xFF};
85 uint32_t offs = 0;
86
87 /* Search direction down -> top */
88 startblock = flash.block_num -1;
89
90 td->page= -1;
91 /* Scan the maximum number of blocks */
92 for (block = 0; block < td->maxblocks; block++)
93 {
94
95 int actblock = startblock -block;
96 offs = actblock << flash.block_size_shift;
97
98 /* Read first page */
99 flash.read_oob(oob_buffer, offs, flash.oob_size);
100 if (!nand_check_pattern(oob_buffer,td))
101 {
102 td->page = actblock << blocktopage;
103 td->version= oob_buffer[td->veroffs];
104
105 break;
106 }
107 }
108
109 return 0;
110}
111
112
113static int nand_read_bbt(struct nand_bbt_descr *td,int num)
114{
115 int bits=2;
116
117 int res, i, j, act = 0;
118 int totlen;
119 int from;
120 uint8_t msk = (uint8_t) ((1 << bits) - 1);
121 totlen = (num * bits) >> 3;
122 from =(td->page)<<(flash.page_size_shift);
123 char* buf;
124
125
126 res = flash.read_page_raw(CFG_TEMP_ADDR, from);
127 if (res < 0)
128 {
129 return -1;
130 }
131
132 buf =(char*) CFG_TEMP_ADDR;
133
134
135 /* Analyse data */
136 for (i = 0; i < totlen; i++)
137 {
138 uint8_t dat = buf[i];
139 for (j = 0; j < 8; j += bits, act += 2)
140 {
141 uint8_t tmp = (dat >> j) & msk;
142 if (tmp == msk)
143 {
144 block_bad_table[(act >> 1)]= 0X0;
145 continue;
146 }
147 else
148 {
149 block_bad_table[(act >> 1)]= BAD_BLOCK;
150 }
151 }
152 }
153
154 return 0;
155}
156
157
158static void nand_init_bbt_descr(struct nand_bbt_descr *td,
159 struct nand_bbt_descr *md)
160{
161 switch(flash.manuf_id)
162 {
163 case NAND_MFR_PARAGON:
164 if(flash.device_id != NAND_DEVID_FDANWEI_1G)
165 {
166 td->offs = BBT_INFO_OOB_OFFSET_PARAGON;
167 md->offs = BBT_INFO_OOB_OFFSET_PARAGON;
168 td->veroffs = BBT_INFO_OOB_VER_OFFSET_PARAGON;
169 md->veroffs = BBT_INFO_OOB_VER_OFFSET_PARAGON;
170 }
171 break;
172 case NAND_MFR_HEYANGTEK:
173 td->offs = BBT_INFO_OOB_OFFSET_HEYANGTEK;
174 md->offs = BBT_INFO_OOB_OFFSET_HEYANGTEK;
175 td->veroffs = BBT_INFO_OOB_VER_OFFSET_HEYANGTEK;
176 md->veroffs =BBT_INFO_OOB_VER_OFFSET_HEYANGTEK;
177 break;
178 default:
179 break;
180 }
181}
182
183int nand_creat_bbt( void )
184{
185 struct nand_bbt_descr *td = &bbt_main_descr;
186 struct nand_bbt_descr *md = &bbt_mirror_descr;
187
188 nand_init_bbt_descr(td, md);
189
190 // 2.0 search main bbt
191 nand_search_bbt(td);
192 // 2.1 search mirror bbt
193 nand_search_bbt(md);
194
195 if(td->page==-1&&md->page ==-1)
196 {
197 /* if failed found bbt, we create a ram bbt */
198 nand_creat_ram_bbt();
199 return 0;
200 }
201
202 // 3.0 read and analyze bbt
203 if(td->page==-1)
204 {
205 nand_read_bbt(md,BBT_SIZE);
206 }
207 else
208 {
209 if(md->page == -1)
210 {
211 nand_read_bbt(td,BBT_SIZE);
212 }
213 else
214 {
215 if(td->version >= md->version)
216 {
217 nand_read_bbt(td,BBT_SIZE);
218 }
219 else
220 {
221 nand_read_bbt(md,BBT_SIZE);
222 }
223 }
224 }
225 printf("bbt ok.\n");
226
227 return 0;
228}
229
230/*******************************************************************************
231 * Function:
232 * Description:
233 * Parameters:
234 * Input:
235 *
236 * Output:
237 *
238 * Returns:
239 *
240 *
241 * Others:
242 ********************************************************************************/
243uint32_t nand_block_isbad(uint32_t offset)
244{
245 uint32_t block_offset = offset >> (flash.block_size_shift);
246 return block_bad_table[block_offset];
247}
248
249
250