Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
301 theseven 1
/***************************************************************************
2
 *             __________               __   ___.
3
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
4
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
5
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
6
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
7
 *                     \/            \/     \/    \/            \/
8
 * $Id$
9
 *
10
 * Copyright (C) 2007 Dave Chapman
11
 *
12
 * This program is free software; you can redistribute it and/or
13
 * modify it under the terms of the GNU General Public License
14
 * as published by the Free Software Foundation; either version 2
15
 * of the License, or (at your option) any later version.
16
 *
17
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18
 * KIND, either express or implied.
19
 *
20
 ****************************************************************************/
21
#include "global.h"
22
#include "thread.h"
23
#include "disk.h"
24
#include "storage.h"
25
#include "timer.h"
26
#include "../ipodnano3g/s5l8702.h"
27
 
28
/** static, private data **/ 
29
uint16_t ata_identify_data[0x100];
30
bool ata_lba48;
31
bool ata_dma;
32
uint64_t ata_total_sectors;
33
static struct mutex ata_mutex;
34
static struct wakeup ata_wakeup;
35
static uint32_t ata_dma_flags;
36
static long ata_last_activity_value = -1;
37
static long ata_sleep_timeout = 20000000;
38
static uint32_t ata_stack[0x80];
39
static bool ata_powered;
40
 
41
 
42
static uint16_t ata_read_cbr(uint32_t volatile* reg)
43
{
44
    while (!(ATA_PIO_READY & 2)) sleep(0);
45
    volatile uint32_t dummy = *reg;
46
    while (!(ATA_PIO_READY & 1)) sleep(0);
47
    return ATA_PIO_RDATA;
48
}
49
 
50
static void ata_write_cbr(uint32_t volatile* reg, uint16_t data)
51
{
52
    while (!(ATA_PIO_READY & 2)) sleep(0);
53
    *reg = data;
54
}
55
 
56
static int ata_wait_for_not_bsy(long timeout)
57
{
58
    long startusec = USEC_TIMER;
59
    while (true)
60
    {
61
        uint8_t csd = ata_read_cbr(&ATA_PIO_CSD);
62
        if (!(csd & BIT(7))) return 0;
63
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(0);
64
        sleep(100);
65
    }
66
}
67
 
68
static int ata_wait_for_rdy(long timeout)
69
{
70
    long startusec = USEC_TIMER;
71
    PASS_RC(ata_wait_for_not_bsy(timeout), 1, 0);
72
    while (true)
73
    {
74
        uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
75
        if (dad & BIT(6)) return 0;
76
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(1);
77
        sleep(100);
78
    }
79
}
80
 
81
static int ata_wait_for_start_of_transfer(long timeout)
82
{
83
    long startusec = USEC_TIMER;
84
    PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0);
85
    while (true)
86
    {
87
        uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
88
        if (dad & BIT(0)) RET_ERR(1);
89
        if ((dad & (BIT(7) | BIT(3))) == BIT(3)) return 0;
90
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(2);
91
        sleep(100);
92
    }
93
}
94
 
95
static int ata_wait_for_end_of_transfer(long timeout)
96
{
97
    PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0);
98
    uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
99
    if (dad & BIT(0)) RET_ERR(1);
100
    if ((dad & (BIT(3) | BITRANGE(5, 7))) == BIT(6)) return 0;
101
    RET_ERR(2);
102
}    
103
 
104
int ata_identify(uint16_t* buf)
105
{
106
    int i;
107
    PASS_RC(ata_wait_for_not_bsy(10000000), 1, 0);
108
    ata_write_cbr(&ATA_PIO_DVR, 0);
109
    ata_write_cbr(&ATA_PIO_CSD, 0xec);
110
    PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1);
111
    for (i = 0; i < 0x100; i++)
112
    {
113
        uint16_t word = ata_read_cbr(&ATA_PIO_DTR);
114
        buf[i] = (word >> 8) | (word << 8);
115
    }
116
}
117
 
118
void ata_set_active(void)
119
{
120
    ata_last_activity_value = USEC_TIMER;
121
}
122
 
123
int ata_power_up()
124
{
125
    ata_set_active();
126
    i2c_sendbyte(0, 0xe6, 0x1b, 1);
127
    clockgate_enable(5, true);
128
    ATA_CFG = BIT(0);
129
    sleep(1000);
130
    ATA_CFG = 0;
131
    sleep(6000);
132
    ATA_SWRST = BIT(0);
133
    sleep(500);
134
    ATA_SWRST = 0;
135
    sleep(90000);
136
    ATA_CONTROL = BIT(0);
137
    sleep(200000);
138
    ATA_PIO_TIME = 0x191f7;
139
    ATA_PIO_LHR = 0;
140
    while (!(ATA_PIO_READY & BIT(1))) sleep(100);
141
    PASS_RC(ata_identify(ata_identify_data), 2, 0);
142
    uint32_t piotime = 0x11f3;
143
    uint32_t mdmatime = 0x1c175;
144
    uint32_t udmatime = 0x5071152;
145
    uint32_t param = 0;
146
    ata_dma_flags = 0;
147
    ata_lba48 = ata_identify_data[83] & BIT(10) ? true : false;
148
    if (ata_lba48)
149
        ata_total_sectors = ata_identify_data[100]
150
                          | (((uint64_t)ata_identify_data[101]) << 16)
151
                          | (((uint64_t)ata_identify_data[102]) << 32)
152
                          | (((uint64_t)ata_identify_data[103]) << 48);
153
    else ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16);
154
    if (ata_identify_data[53] & BIT(1))
155
    {
156
        if (ata_identify_data[64] & BIT(1)) piotime = 0x2072;
157
        else if (ata_identify_data[64] & BIT(0)) piotime = 0x7083;
158
    }
159
    if (ata_identify_data[63] & BIT(2))
160
    {
161
        mdmatime = 0x5072;
162
        param = 0x22;
163
    }
164
    else if (ata_identify_data[63] & BIT(1))
165
    {
166
        mdmatime = 0x7083;
167
        param = 0x21;
168
    }
169
    if (ata_identify_data[63] & BITRANGE(0, 2))
170
    {
171
        ata_dma_flags = BIT(3) | BIT(10);
172
        param |= 0x20;
173
    }
174
    if (ata_identify_data[53] & BIT(2))
175
    {
176
        if (ata_identify_data[88] & BIT(4))
177
        {
178
            udmatime = 0x2010a52;
179
            param = 0x44;
180
        }
181
        else if (ata_identify_data[88] & BIT(3))
182
        {
183
            udmatime = 0x2020a52;
184
            param = 0x43;
185
        }
186
        else if (ata_identify_data[88] & BIT(2))
187
        {
188
            udmatime = 0x3030a52;
189
            param = 0x42;
190
        }
191
        else if (ata_identify_data[88] & BIT(1))
192
        {
193
            udmatime = 0x3050a52;
194
            param = 0x41;
195
        }
196
        if (ata_identify_data[88] & BITRANGE(0, 4))
197
        {
198
            ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10);
199
            param |= 0x40;
200
        }
201
    }
202
    ata_dma = param ? true : false;
203
    PASS_RC(ata_wait_for_rdy(500000), 2, 1);
204
    ata_write_cbr(&ATA_PIO_DVR, 0);
205
    ata_write_cbr(&ATA_PIO_FED, 3);
206
    ata_write_cbr(&ATA_PIO_SCR, param);
207
    ata_write_cbr(&ATA_PIO_CSD, 0xef);
208
    PASS_RC(ata_wait_for_rdy(500000), 2, 2);
209
    ATA_PIO_TIME = piotime;
210
    ATA_MDMA_TIME = mdmatime;
211
    ATA_UDMA_TIME = udmatime;
212
    ata_powered = true;
213
    ata_set_active();
214
    return 0;
215
}
216
 
217
void ata_power_down()
218
{
219
    ata_powered = false;
220
    ata_wait_for_rdy(1000000);
221
    ata_write_cbr(&ATA_PIO_DVR, 0);
222
    ata_write_cbr(&ATA_PIO_CSD, 0xe0);
223
    ata_wait_for_rdy(1000000);
224
    sleep(30000);
225
    ATA_CONTROL = 0;
226
    while (!(ATA_CONTROL & BIT(1))) sleep(0);
227
    clockgate_enable(5, false);
228
    i2c_sendbyte(0, 0xe6, 0x1b, 0);
229
}
230
 
231
int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write)
232
{
233
    if (sector + count > ata_total_sectors) RET_ERR(0);
234
    if (!ata_powered) ata_power_up();
235
    ata_set_active();
236
    if (ata_dma && write) clean_dcache();
237
    else if (ata_dma) invalidate_dcache();
238
    ATA_COMMAND = BIT(1);
239
    while (count)
240
    {
241
        uint32_t cnt = MIN(64, count);
242
        PASS_RC(ata_wait_for_rdy(100000), 2, 0);
243
        ata_write_cbr(&ATA_PIO_DVR, 0);
244
        if (ata_lba48)
245
        {
246
            ata_write_cbr(&ATA_PIO_SCR, cnt >> 5);
247
            ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
248
            ata_write_cbr(&ATA_PIO_LHR, (sector >> 37) & 0xff);
249
            ata_write_cbr(&ATA_PIO_LMR, (sector >> 29) & 0xff);
250
            ata_write_cbr(&ATA_PIO_LLR, (sector >> 21) & 0xff);
251
            ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
252
            ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
253
            ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
254
            ata_write_cbr(&ATA_PIO_DVR, BIT(6));
255
            if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x35 : 0x39);
256
            else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x25 : 0x29);
257
        }
258
        else
259
        {
260
            ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
261
            ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
262
            ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
263
            ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
264
            ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 21) & 0xf));
265
            if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xca : 0x30);
266
            else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xc8 : 0xc4);
267
        }
268
        sector += cnt;
269
        count -= cnt;
270
        if (ata_dma)
271
        {
272
            if (write)
273
            {
274
                ATA_SBUF_START = buffer;
275
                ATA_SBUF_SIZE = SECTOR_SIZE * cnt;
276
                ATA_CFG |= BIT(4);
277
            }
278
            else
279
            {
280
                ATA_TBUF_START = buffer;
281
                ATA_TBUF_SIZE = SECTOR_SIZE * cnt;
282
                ATA_CFG &= ~BIT(4);
283
            }
284
            ATA_XFR_NUM = SECTOR_SIZE * cnt - 1;
285
            ATA_CFG |= ata_dma_flags;
286
            ATA_CFG &= ~(BIT(7) | BIT(8));
287
            wakeup_wait(&ata_wakeup, TIMEOUT_NONE);
288
            ATA_IRQ = BITRANGE(0, 4);
289
            ATA_IRQ_MASK = BIT(0);
290
            ATA_COMMAND = BIT(0);
291
            if (wakeup_wait(&ata_wakeup, 3000000) == THREAD_TIMEOUT)
292
            {
293
                ATA_COMMAND = BIT(1);
294
                ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
295
                RET_ERR(2);
296
            }
297
            ATA_COMMAND = BIT(1);
298
            ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
299
            buffer += SECTOR_SIZE * cnt;
300
        }
301
        else
302
        {
303
            cnt *= SECTOR_SIZE / 512;
304
            while (cnt--)
305
            {
306
                int i;
307
                PASS_RC(ata_wait_for_start_of_transfer(3000000), 2, 1);
308
                if (write)
309
                    for (i = 0; i < 256; i++)
310
                        ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]);
311
                else
312
                    for (i = 0; i < 256; i++)
313
                        ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR);
314
                buffer += 512;
315
            }
316
        }
317
        PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3);
318
    }
319
    ata_set_active();
320
    return 0;
321
}
322
 
323
static void ata_thread(void)
324
{
325
    while (true)
326
    {
327
        mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
328
        if (TIME_AFTER(USEC_TIMER, ata_last_activity_value + ata_sleep_timeout) && ata_powered)
329
            ata_power_down();
330
        mutex_unlock(&ata_mutex);
331
        sleep(1000000);
332
    }
333
}
334
 
335
/* API Functions */
336
int ata_soft_reset()
337
{
338
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
339
    if (!ata_powered) ata_power_up();
340
    ata_set_active();
341
    ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2));
342
    sleep(10);
343
    ata_write_cbr(&ATA_PIO_DAD, 0);
344
    PASS_RC_MTX(ata_wait_for_rdy(5000000), 0, 0, &ata_mutex);
345
    ata_set_active();
346
    mutex_unlock(&ata_mutex);
347
}
348
 
349
int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
350
                     void* inbuf)
351
{
352
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
353
    int tries = 5;
354
    int rc = -1;
355
    while (--tries && rc)
356
    {
357
        rc = ata_rw_sectors(start, incount, inbuf, false);
358
        if (rc) ata_soft_reset();
359
    }
360
    mutex_unlock(&ata_mutex);
361
    return rc;
362
}
363
 
364
int ata_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
365
                      const void* outbuf)
366
{
367
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
368
    int tries = 5;
369
    int rc = -1;
370
    while (--tries && rc)
371
    {
372
        rc = ata_rw_sectors(start, count, (void*)((uint32_t)outbuf), true);
373
        if (rc) ata_soft_reset();
374
    }
375
    mutex_unlock(&ata_mutex);
376
    return rc;
377
}
378
 
379
void ata_spindown(int seconds)
380
{
381
    ata_sleep_timeout = seconds * 1000000;
382
}
383
 
384
void ata_sleep(void)
385
{
386
    call_storage_idle_notifys(false);
387
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
388
    ata_power_down();
389
    mutex_unlock(&ata_mutex);
390
}
391
 
392
void ata_sleepnow(void)
393
{
394
    ata_sleep();
395
}
396
 
397
void ata_close(void)
398
{
399
    ata_sleep();
400
}
401
 
402
void ata_spin(void)
403
{
404
    ata_power_up();
405
}
406
 
407
void ata_get_info(IF_MD2(int drive,) struct storage_info *info)
408
{
409
    (*info).sector_size = SECTOR_SIZE;
410
    (*info).num_sectors = ata_total_sectors;
411
    (*info).vendor = "Apple";
412
    (*info).product = "iPod Classic";
413
    (*info).revision = "1.0";
414
}
415
 
416
long ata_last_disk_activity(void)
417
{
418
    return ata_last_activity_value;
419
}
420
 
421
int ata_init(void)
422
{
423
    mutex_init(&ata_mutex);
424
    wakeup_init(&ata_wakeup);
425
    PCON(7) = 0x44444444;
426
    PCON(8) = 0x44444444;
427
    PCON(9) = 0x44444444;
428
    PCON(10) = (PCON(10) & ~0xffff) | 0x4444;
429
    ata_powered = false;
430
    ata_total_sectors = 0;
431
    thread_create("ATA idle monitor", ata_thread, ata_stack,
432
                  sizeof(ata_stack), USER_THREAD, 1, true);
433
    return 0;
434
}
435
 
436
#ifdef CONFIG_STORAGE_MULTI
437
int ata_num_drives(int first_drive)
438
{
439
    /* We don't care which logical drive number(s) we have been assigned */
440
    (void)first_drive;
441
 
442
    return 1;
443
}
444
#endif
445
 
446
void INT_ATA()
447
{
448
    uint32_t ata_irq = ATA_IRQ;
449
    ATA_IRQ = ata_irq;
450
    if (ata_irq & ATA_IRQ_MASK) wakeup_signal(&ata_wakeup);
451
    ATA_IRQ_MASK = 0;
452
}