tree browser: return native path delimiters in returned path
[Rockbox.git] / firmware / drivers / ata_flash.c
blobccdc8c2443995f3a2ca260c1a56837ff5d88b0e4
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 Tomasz Malesinski
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "ata.h"
21 #include <stdbool.h>
22 #include <string.h>
24 #if CONFIG_CPU == PNX0101
25 #include "pnx0101.h"
26 #endif
29 #include "kernel.h"
30 #include "thread.h"
31 #include "led.h"
32 #include "cpu.h"
33 #include "system.h"
34 #include "debug.h"
35 #include "panic.h"
36 #include "usb.h"
37 #include "power.h"
38 #include "string.h"
41 #define SECTOR_SIZE (512)
43 static unsigned short identify_info[SECTOR_SIZE];
44 int ata_spinup_time = 0;
45 long last_disk_activity = -1;
47 #if CONFIG_FLASH == FLASH_IFP7XX
48 static unsigned char flash_ce[4] = {0x20, 0x02, 0x10, 0x08};
50 #define FLASH_IO_BASE 0x28000000
51 #define FLASH_REG_DATA (*((volatile unsigned char*)(FLASH_IO_BASE)))
52 #define FLASH_REG_CMD (*((volatile unsigned char*)(FLASH_IO_BASE + 4)))
53 #define FLASH_REG_ADDR (*((volatile unsigned char*)(FLASH_IO_BASE + 8)))
55 #define SEGMENT_SIZE 1000
56 #define MAX_N_SEGMENTS 8
58 #endif
60 #define FLASH_MODEL_NONE 0
61 #define FLASH_MODEL_256 1
62 #define FLASH_MODEL_512 2
64 struct flash_disk
66 unsigned short block_map[MAX_N_SEGMENTS][SEGMENT_SIZE];
67 short cur_block;
68 int cur_phblock_start;
69 int n_chips;
70 unsigned char chip_no[4];
71 unsigned char model;
74 static struct flash_disk flash_disk;
76 void flash_select_chip(int no, int sel)
78 #if CONFIG_FLASH == FLASH_IFP7XX
79 if (sel)
80 GPIO5_CLR = flash_ce[no];
81 else
82 GPIO5_SET = flash_ce[no];
83 #endif
86 static inline unsigned char flash_read_data(void)
88 return FLASH_REG_DATA;
91 static inline void flash_write_data(unsigned char data)
93 FLASH_REG_DATA = data;
96 /* TODO: these two doesn't work when inlined, probably some
97 delay is required */
99 static void flash_write_cmd(unsigned char cmd)
101 FLASH_REG_CMD = cmd;
104 static void flash_write_addr(unsigned char addr)
106 FLASH_REG_ADDR = addr;
109 static void flash_wait_ready(void)
111 int i;
112 for (i = 0; i < 5; i++)
113 while ((GPIO6_READ & 8) == 0);
116 static unsigned char model_n_sectors_order[] = {0, 19, 20};
118 int flash_map_sector(int sector, int* chip, int* chip_sector)
120 int ord, c;
121 if (flash_disk.model == FLASH_MODEL_NONE)
122 return -1;
124 ord = model_n_sectors_order[flash_disk.model];
125 c = sector >> ord;
126 *chip_sector = sector & ((1 << ord) - 1);
128 if (c >= flash_disk.n_chips)
129 return -1;
131 *chip = flash_disk.chip_no[c];
132 return 0;
135 int flash_read_id(int no) {
136 int id;
138 flash_select_chip(no, 1);
139 flash_write_cmd(0x90);
140 flash_write_addr(0);
142 flash_read_data();
143 id = flash_read_data();
145 flash_select_chip(no, 0);
146 return id;
149 int flash_read_sector(int sector, unsigned char* buf,
150 unsigned char* oob)
152 int chip, chip_sector;
153 int i;
155 if (flash_map_sector(sector, &chip, &chip_sector) < 0)
156 return -1;
158 flash_select_chip(chip, 1);
160 flash_write_cmd(0x00);
161 flash_write_addr(0);
162 flash_write_addr((chip_sector << 1) & 7);
163 flash_write_addr((chip_sector >> 2) & 0xff);
164 flash_write_addr((chip_sector >> 10) & 0xff);
165 flash_write_addr((chip_sector >> 18) & 0xff);
166 flash_write_cmd(0x30);
168 flash_wait_ready();
170 for (i = 0; i < 512; i++)
171 buf[i] = flash_read_data();
173 flash_write_cmd(0x05);
174 flash_write_addr((chip_sector & 3) * 0x10);
175 flash_write_addr(8);
176 flash_write_cmd(0xe0);
178 for (i = 0; i < 16; i++)
179 oob[i] = flash_read_data();
181 flash_select_chip(chip, 0);
182 return 0;
185 int flash_read_sector_oob(int sector, unsigned char* oob)
187 int chip, chip_sector;
188 int i;
190 if (flash_map_sector(sector, &chip, &chip_sector) < 0)
191 return -1;
193 flash_select_chip(chip, 1);
195 flash_write_cmd(0x00);
196 flash_write_addr((chip_sector & 3) * 0x10);
197 flash_write_addr(8);
198 flash_write_addr((chip_sector >> 2) & 0xff);
199 flash_write_addr((chip_sector >> 10) & 0xff);
200 flash_write_addr((chip_sector >> 18) & 0xff);
201 flash_write_cmd(0x30);
203 flash_wait_ready();
205 for (i = 0; i < 16; i++)
206 oob[i] = flash_read_data();
208 flash_select_chip(chip, 0);
209 return 0;
212 static unsigned char model_n_segments[] = {0, 2, 4};
214 static inline int flash_get_n_segments(void)
216 return model_n_segments[flash_disk.model] * flash_disk.n_chips;
219 static inline int flash_get_n_phblocks(void)
221 return 1024;
224 static int model_n_sectors_in_block[] = {0, 256, 256};
226 static int flash_get_n_sectors_in_block(void)
228 return model_n_sectors_in_block[flash_disk.model];
231 static int flash_phblock_to_sector(int segment, int block)
233 return (segment * flash_get_n_phblocks() + block)
234 * flash_get_n_sectors_in_block();
237 static int flash_is_bad_block(unsigned char* oob)
239 /* TODO: should we check two pages? (see datasheet) */
240 return oob[0] != 0xff;
243 static int count_1(int n) {
244 int r = 0;
245 while (n != 0) {
246 r += (n & 1);
247 n >>= 1;
249 return r;
252 static int flash_get_logical_block_no(unsigned char* oob)
254 int no1, no2;
255 no1 = oob[6] + (oob[7] << 8);
256 no2 = oob[11] + (oob[12] << 8);
258 if (no1 == no2 && (no1 & 0xf000) == 0x1000)
259 return (no1 & 0xfff) >> 1;
261 if (count_1(no1 ^ no2) > 1)
262 return -1;
264 if ((no1 & 0xf000) == 0x1000
265 && (count_1(no1) & 1) == 0)
266 return (no1 & 0xfff) >> 1;
268 if ((no2 & 0xf000) == 0x1000
269 && (count_1(no2) & 1) == 0)
270 return (no2 & 0xfff) >> 1;
272 return -1;
275 int flash_disk_scan(void)
277 int n_segments, n_phblocks;
278 unsigned char oob[16];
279 int s, b;
281 /* TODO: checking for double blocks */
283 n_segments = flash_get_n_segments();
284 n_phblocks = flash_get_n_phblocks();
286 flash_disk.cur_block = -1;
287 flash_disk.cur_phblock_start = -1;
289 for (s = 0; s < n_segments; s++)
291 for (b = 0; b < n_phblocks; b++)
293 int r;
294 r = flash_read_sector_oob(flash_phblock_to_sector(s, b),
295 oob);
296 if (r >= 0 && !flash_is_bad_block(oob))
298 int lb;
299 lb = flash_get_logical_block_no(oob);
300 if (lb >= 0 && lb < SEGMENT_SIZE)
301 flash_disk.block_map[s][lb] = b;
305 return 0;
308 int flash_disk_find_block(int block)
310 int seg, bmod, phb;
311 unsigned char oob[16];
312 int r;
314 if (block >= SEGMENT_SIZE * flash_get_n_segments())
315 return -1;
317 if (block == flash_disk.cur_block)
318 return flash_disk.cur_phblock_start;
320 seg = block / SEGMENT_SIZE;
321 bmod = block % SEGMENT_SIZE;
323 phb = flash_disk.block_map[seg][bmod];
324 r = flash_read_sector_oob(flash_phblock_to_sector(seg, phb), oob);
325 if (r < 0)
326 return -1;
327 if (flash_is_bad_block(oob))
328 return -1;
329 if (flash_get_logical_block_no(oob) != bmod)
330 return -1;
332 flash_disk.cur_block = block;
333 flash_disk.cur_phblock_start = flash_phblock_to_sector(seg, phb);
334 return flash_disk.cur_phblock_start;
337 int flash_disk_read_sectors(unsigned long start,
338 int count,
339 void* buf)
341 int block, secmod, done;
342 int phb;
343 char oob[16];
345 block = start / flash_get_n_sectors_in_block();
346 secmod = start % flash_get_n_sectors_in_block();
348 phb = flash_disk_find_block(block);
349 done = 0;
350 while (count > 0 && secmod < flash_get_n_sectors_in_block())
352 if (phb >= 0)
353 flash_read_sector(phb + secmod, buf, oob);
354 else
355 memset(buf, 0, SECTOR_SIZE);
357 buf += SECTOR_SIZE;
358 count--;
359 secmod++;
360 done++;
362 return done;
365 int ata_read_sectors(IF_MV2(int drive,)
366 unsigned long start,
367 int incount,
368 void* inbuf)
370 while (incount > 0)
372 int done = flash_disk_read_sectors(start, incount, inbuf);
373 if (done < 0)
374 return -1;
375 start += done;
376 incount -= done;
377 inbuf += SECTOR_SIZE * done;
379 return 0;
382 int ata_write_sectors(IF_MV2(int drive,)
383 unsigned long start,
384 int count,
385 const void* buf)
387 (void)start;
388 (void)count;
389 (void)buf;
390 return -1;
393 /* schedule a single sector write, executed with the the next spinup
394 (volume 0 only, used for config sector) */
395 extern void ata_delayed_write(unsigned long sector, const void* buf)
397 (void)sector;
398 (void)buf;
401 /* write the delayed sector to volume 0 */
402 extern void ata_flush(void)
407 void ata_spindown(int seconds)
409 (void)seconds;
412 bool ata_disk_is_active(void)
414 return 0;
417 void ata_sleep(void)
421 void ata_spin(void)
425 /* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
426 int ata_hard_reset(void)
428 return 0;
431 int ata_soft_reset(void)
433 return 0;
436 void ata_enable(bool on)
438 (void)on;
441 unsigned short* ata_get_identify(void)
443 return identify_info;
446 int ata_init(void)
448 int i, id, id2;
450 id = flash_read_id(0);
451 switch (id)
453 case 0xda:
454 flash_disk.model = FLASH_MODEL_256;
455 break;
456 case 0xdc:
457 flash_disk.model = FLASH_MODEL_512;
458 break;
459 default:
460 flash_disk.model = FLASH_MODEL_NONE;
461 return -1;
464 flash_disk.n_chips = 1;
465 flash_disk.chip_no[0] = 0;
466 for (i = 1; i < 4; i++)
468 id2 = flash_read_id(i);
469 if (id2 == id)
470 flash_disk.chip_no[flash_disk.n_chips++] = i;
473 if (flash_disk_scan() < 0)
474 return -2;
476 return 0;