summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2006-01-18 10:01:35 +0000
committerDave Chapman <dave@dchapman.com>2006-01-18 10:01:35 +0000
commit205be712fe6ad03f194216bc0f936f1b5917eafd (patch)
treefbb5cf109c2fd86542e121a858ca00c4b166af28
parenta8c408c6a3049dc49e27f39008dff0001bf581bc (diff)
downloadrockbox-205be712fe6ad03f194216bc0f936f1b5917eafd.tar.gz
rockbox-205be712fe6ad03f194216bc0f936f1b5917eafd.zip
Two files for the iFP port that I forgot to commit
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8365 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/ata_flash.c454
-rw-r--r--firmware/drivers/i2c-pnx0101.c22
2 files changed, 476 insertions, 0 deletions
diff --git a/firmware/drivers/ata_flash.c b/firmware/drivers/ata_flash.c
new file mode 100644
index 0000000000..17796e0d50
--- /dev/null
+++ b/firmware/drivers/ata_flash.c
@@ -0,0 +1,454 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Tomasz Malesinski
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "ata.h"
21#include <stdbool.h>
22#include <string.h>
23
24#if CONFIG_CPU == PNX0101
25#include "pnx0101.h"
26#endif
27
28/*
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"
39#include "hwcompat.h"
40*/
41
42#define SECTOR_SIZE (512)
43
44static unsigned short identify_info[SECTOR_SIZE];
45int ata_spinup_time = 0;
46long last_disk_activity = -1;
47
48#if CONFIG_FLASH == FLASH_IFP7XX
49static unsigned char flash_ce[4] = {0x20, 0x02, 0x10, 0x08};
50
51#define FLASH_IO_BASE 0x28000000
52#define FLASH_REG_DATA (*((volatile unsigned char*)(FLASH_IO_BASE)))
53#define FLASH_REG_CMD (*((volatile unsigned char*)(FLASH_IO_BASE + 4)))
54#define FLASH_REG_ADDR (*((volatile unsigned char*)(FLASH_IO_BASE + 8)))
55
56#define SEGMENT_SIZE 1000
57#define MAX_N_SEGMENTS 2
58
59#endif
60
61#define FLASH_MODEL_NONE 0
62#define FLASH_MODEL_256 1
63
64struct flash_disk
65{
66 short model;
67 unsigned short block_map[MAX_N_SEGMENTS][SEGMENT_SIZE];
68 short cur_block;
69 int cur_phblock_start;
70};
71
72static struct flash_disk flash_disk;
73
74void flash_select_chip(int no, int sel)
75{
76#if CONFIG_FLASH == FLASH_IFP7XX
77 if (sel)
78 GPIO5_CLR = flash_ce[no];
79 else
80 GPIO5_SET = flash_ce[no];
81#endif
82}
83
84unsigned char flash_read_data(void)
85{
86 return FLASH_REG_DATA;
87}
88
89void flash_write_data(unsigned char data)
90{
91 FLASH_REG_DATA = data;
92}
93
94void flash_write_cmd(unsigned char cmd)
95{
96 FLASH_REG_CMD = cmd;
97}
98
99void flash_write_addr(unsigned char addr)
100{
101 FLASH_REG_ADDR = addr;
102}
103
104void flash_wait_ready(void)
105{
106 int i;
107 for (i = 0; i < 5; i++)
108 while ((GPIO6_READ & 8) == 0);
109}
110
111int flash_map_sector(int sector, int* chip, int* chip_sector)
112{
113 switch (flash_disk.model)
114 {
115 case FLASH_MODEL_NONE:
116 default:
117 return -1;
118 case FLASH_MODEL_256:
119 *chip = 0;
120 *chip_sector = sector;
121 return 0;
122 }
123}
124
125int flash_read_id(int no) {
126 int id;
127
128 flash_select_chip(no, 1);
129 flash_write_cmd(0x90);
130 flash_write_addr(0);
131
132 flash_read_data();
133 id = flash_read_data();
134
135 flash_select_chip(no, 0);
136 return id;
137}
138
139int flash_read_sector(int sector, unsigned char* buf,
140 unsigned char* oob)
141{
142 int chip, chip_sector;
143 int i;
144
145 if (flash_map_sector(sector, &chip, &chip_sector) < 0)
146 return -1;
147
148 flash_select_chip(chip, 1);
149
150 flash_write_cmd(0x00);
151 flash_write_addr(0);
152 flash_write_addr((chip_sector << 1) & 7);
153 flash_write_addr((chip_sector >> 2) & 0xff);
154 flash_write_addr((chip_sector >> 10) & 0xff);
155 flash_write_addr((chip_sector >> 18) & 0xff);
156 flash_write_cmd(0x30);
157
158 flash_wait_ready();
159
160 for (i = 0; i < 512; i++)
161 buf[i] = flash_read_data();
162
163 flash_write_cmd(0x05);
164 flash_write_addr((chip_sector & 3) * 0x10);
165 flash_write_addr(8);
166 flash_write_cmd(0xe0);
167
168 for (i = 0; i < 16; i++)
169 oob[i] = flash_read_data();
170
171 flash_select_chip(chip, 0);
172 return 0;
173}
174
175int flash_read_sector_oob(int sector, unsigned char* oob)
176{
177 int chip, chip_sector;
178 int i;
179
180 if (flash_map_sector(sector, &chip, &chip_sector) < 0)
181 return -1;
182
183 flash_select_chip(chip, 1);
184
185 flash_write_cmd(0x00);
186 flash_write_addr((chip_sector & 3) * 0x10);
187 flash_write_addr(8);
188 flash_write_addr((chip_sector >> 2) & 0xff);
189 flash_write_addr((chip_sector >> 10) & 0xff);
190 flash_write_addr((chip_sector >> 18) & 0xff);
191 flash_write_cmd(0x30);
192
193 flash_wait_ready();
194
195 for (i = 0; i < 16; i++)
196 oob[i] = flash_read_data();
197
198 flash_select_chip(chip, 0);
199 return 0;
200}
201
202static unsigned char model_n_segments[] = {0, 2};
203
204static int flash_get_n_segments(void)
205{
206 return model_n_segments[flash_disk.model];
207}
208
209static int flash_get_n_phblocks(void)
210{
211 return 1024;
212}
213
214static int model_n_sectors_in_block[] = {0, 256};
215
216static int flash_get_n_sectors_in_block(void)
217{
218 return model_n_sectors_in_block[flash_disk.model];
219}
220
221static int flash_phblock_to_sector(int segment, int block)
222{
223 return (segment * flash_get_n_phblocks() + block)
224 * flash_get_n_sectors_in_block();
225}
226
227static int flash_is_bad_block(unsigned char* oob)
228{
229 /* TODO: should we check two pages? (see datasheet) */
230 return oob[0] != 0xff;
231}
232
233static int count_1(int n) {
234 int r = 0;
235 while (n != 0) {
236 r += (n & 1);
237 n >>= 1;
238 }
239 return r;
240}
241
242static int flash_get_logical_block_no(unsigned char* oob)
243{
244 int no1, no2;
245 no1 = oob[6] + (oob[7] << 8);
246 no2 = oob[11] + (oob[12] << 8);
247
248 if (no1 == no2 && (no1 & 0xf000) == 0x1000)
249 return (no1 & 0xfff) >> 1;
250
251 if (count_1(no1 ^ no2) > 1)
252 return -1;
253
254 if ((no1 & 0xf000) == 0x1000
255 && (count_1(no1) & 1) == 0)
256 return (no1 & 0xfff) >> 1;
257
258 if ((no2 & 0xf000) == 0x1000
259 && (count_1(no2) & 1) == 0)
260 return (no2 & 0xfff) >> 1;
261
262 return -1;
263}
264
265int flash_disk_scan(void)
266{
267 int n_segments, n_phblocks;
268 unsigned char oob[16];
269 int s, b;
270
271 /* TODO: checking for double blocks */
272
273 n_segments = flash_get_n_segments();
274 n_phblocks = flash_get_n_phblocks();
275
276 flash_disk.cur_block = -1;
277 flash_disk.cur_phblock_start = -1;
278
279 for (s = 0; s < n_segments; s++)
280 {
281 for (b = 0; b < n_phblocks; b++)
282 {
283 int r;
284 r = flash_read_sector_oob(flash_phblock_to_sector(s, b),
285 oob);
286 if (r >= 0 && !flash_is_bad_block(oob))
287 {
288 int lb;
289 lb = flash_get_logical_block_no(oob);
290 if (lb >= 0 && lb < SEGMENT_SIZE)
291 flash_disk.block_map[s][lb] = b;
292 }
293 }
294 }
295 return 0;
296}
297
298int flash_disk_find_block(int block)
299{
300 int seg, bmod, phb;
301 unsigned char oob[16];
302 int r;
303
304 if (block >= SEGMENT_SIZE * flash_get_n_segments())
305 return -1;
306
307 if (block == flash_disk.cur_block)
308 return flash_disk.cur_phblock_start;
309
310 seg = block / SEGMENT_SIZE;
311 bmod = block % SEGMENT_SIZE;
312
313 phb = flash_disk.block_map[seg][bmod];
314 r = flash_read_sector_oob(flash_phblock_to_sector(seg, phb), oob);
315 if (r < 0)
316 return -1;
317 if (flash_is_bad_block(oob))
318 return -1;
319 if (flash_get_logical_block_no(oob) != bmod)
320 return -1;
321
322 flash_disk.cur_block = block;
323 flash_disk.cur_phblock_start = flash_phblock_to_sector(seg, phb);
324 return flash_disk.cur_phblock_start;
325}
326
327int flash_disk_read_sectors(unsigned long start,
328 int count,
329 void* buf)
330{
331 int block, secmod, done;
332 int phb;
333 char oob[16];
334
335 block = start / flash_get_n_sectors_in_block();
336 secmod = start % flash_get_n_sectors_in_block();
337
338 phb = flash_disk_find_block(block);
339 done = 0;
340 while (count > 0 && secmod < flash_get_n_sectors_in_block())
341 {
342 if (phb >= 0)
343 flash_read_sector(phb + secmod, buf, oob);
344 else
345 memset(buf, 0, SECTOR_SIZE);
346
347 buf += SECTOR_SIZE;
348 count--;
349 secmod++;
350 done++;
351 }
352 return done;
353}
354
355int ata_read_sectors(IF_MV2(int drive,)
356 unsigned long start,
357 int incount,
358 void* inbuf)
359{
360 while (incount > 0)
361 {
362 int done = flash_disk_read_sectors(start, incount, inbuf);
363 if (done < 0)
364 return -1;
365 incount -= done;
366 inbuf += SECTOR_SIZE * done;
367 }
368 return 0;
369}
370
371int ata_write_sectors(IF_MV2(int drive,)
372 unsigned long start,
373 int count,
374 const void* buf)
375{
376 (void)start;
377 (void)count;
378 (void)buf;
379 return -1;
380}
381
382/* schedule a single sector write, executed with the the next spinup
383 (volume 0 only, used for config sector) */
384extern void ata_delayed_write(unsigned long sector, const void* buf)
385{
386 (void)sector;
387 (void)buf;
388}
389
390/* write the delayed sector to volume 0 */
391extern void ata_flush(void)
392{
393
394}
395
396void ata_spindown(int seconds)
397{
398 (void)seconds;
399}
400
401bool ata_disk_is_active(void)
402{
403 return 0;
404}
405
406void ata_sleep(void)
407{
408}
409
410void ata_spin(void)
411{
412}
413
414/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
415int ata_hard_reset(void)
416{
417 return 0;
418}
419
420int ata_soft_reset(void)
421{
422 return 0;
423}
424
425void ata_enable(bool on)
426{
427 (void)on;
428}
429
430unsigned short* ata_get_identify(void)
431{
432 return identify_info;
433}
434
435int ata_init(void)
436{
437 int id;
438
439 id = flash_read_id(0);
440 switch (id)
441 {
442 case 0xda:
443 flash_disk.model = FLASH_MODEL_256;
444 break;
445 default:
446 flash_disk.model = FLASH_MODEL_NONE;
447 return -1;
448 }
449
450 if (flash_disk_scan() < 0)
451 return -2;
452
453 return 0;
454}
diff --git a/firmware/drivers/i2c-pnx0101.c b/firmware/drivers/i2c-pnx0101.c
new file mode 100644
index 0000000000..b0c74e8c24
--- /dev/null
+++ b/firmware/drivers/i2c-pnx0101.c
@@ -0,0 +1,22 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Tomasz Malesinski
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20void i2c_init(void)
21{
22}