Subversion Repositories freemyipod

Rev

Go to most recent revision | 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"
339 theseven 25
#include "storage_ata-target.h"
301 theseven 26
#include "timer.h"
629 theseven 27
#include "constants/mmc.h"
301 theseven 28
#include "../ipodnano3g/s5l8702.h"
29
 
613 theseven 30
 
31
#ifndef ATA_RETRIES
32
#define ATA_RETRIES 3
33
#endif
34
 
35
 
629 theseven 36
#define CEATA_POWERUP_TIMEOUT 30000000
37
#define CEATA_COMMAND_TIMEOUT 1000000
38
#define CEATA_DAT_NONBUSY_TIMEOUT 5000000
39
#define CEATA_MMC_RCA 1
40
 
41
 
301 theseven 42
/** static, private data **/ 
629 theseven 43
static uint8_t ceata_taskfile[16] __attribute__((aligned(16)));
301 theseven 44
uint16_t ata_identify_data[0x100];
629 theseven 45
bool ceata;
301 theseven 46
bool ata_lba48;
47
bool ata_dma;
48
uint64_t ata_total_sectors;
601 theseven 49
struct mutex ata_mutex;
301 theseven 50
static struct wakeup ata_wakeup;
51
static uint32_t ata_dma_flags;
52
static long ata_last_activity_value = -1;
53
static long ata_sleep_timeout = 20000000;
429 theseven 54
static struct scheduler_thread ata_thread_handle;
55
static uint32_t ata_stack[0x80] STACK_ATTR;
301 theseven 56
static bool ata_powered;
620 theseven 57
static int ata_retries = ATA_RETRIES;
58
static bool ata_error_srst = true;
629 theseven 59
static struct wakeup mmc_wakeup;
60
static struct wakeup mmc_comp_wakeup;
301 theseven 61
 
629 theseven 62
 
328 theseven 63
#ifdef ATA_HAVE_BBT
64
#include "panic.h"
430 theseven 65
uint16_t (*ata_bbt)[0x20];
339 theseven 66
uint64_t ata_virtual_sectors;
337 theseven 67
uint32_t ata_last_offset;
68
uint64_t ata_last_phys;
301 theseven 69
 
620 theseven 70
int ata_bbt_read_sectors(uint32_t sector, uint32_t count, void* buffer)
328 theseven 71
{
620 theseven 72
    if (ata_last_phys != sector - 1 && ata_last_phys > sector - 64) ata_soft_reset();
328 theseven 73
    int rc = ata_rw_sectors_internal(sector, count, buffer, false);
620 theseven 74
    if (rc) rc = ata_rw_sectors_internal(sector, count, buffer, false);
75
    ata_last_phys = sector + count - 1;
76
    ata_last_offset = 0;
328 theseven 77
    if (IS_ERR(rc))
620 theseven 78
        cprintf(CONSOLE_BOOT, "ATA: Error %08X while reading BBT (sector %d, count %d)\n",
79
                rc, sector, count);
80
    return rc;
328 theseven 81
}
82
#endif
83
 
613 theseven 84
static struct ata_target_driverinfo drvinfo =
85
{
620 theseven 86
    .set_retries = ata_set_retries,
87
    .srst_after_error = ata_srst_after_error,
613 theseven 88
#ifdef ATA_HAVE_BBT
89
    .bbt_translate = ata_bbt_translate,
90
    .bbt_reload = ata_bbt_reload,
91
    .bbt_disable = ata_bbt_disable
92
#endif
93
};
328 theseven 94
 
613 theseven 95
 
620 theseven 96
void ata_set_retries(int retries)
97
{
98
    ata_retries = retries;
99
}
100
 
101
void ata_srst_after_error(bool enable)
102
{
103
    ata_error_srst = enable;
104
}
105
 
301 theseven 106
static uint16_t ata_read_cbr(uint32_t volatile* reg)
107
{
317 theseven 108
    while (!(ATA_PIO_READY & 2)) yield();
301 theseven 109
    volatile uint32_t dummy = *reg;
317 theseven 110
    while (!(ATA_PIO_READY & 1)) yield();
301 theseven 111
    return ATA_PIO_RDATA;
112
}
113
 
114
static void ata_write_cbr(uint32_t volatile* reg, uint16_t data)
115
{
317 theseven 116
    while (!(ATA_PIO_READY & 2)) yield();
301 theseven 117
    *reg = data;
118
}
119
 
120
static int ata_wait_for_not_bsy(long timeout)
121
{
122
    long startusec = USEC_TIMER;
123
    while (true)
124
    {
125
        uint8_t csd = ata_read_cbr(&ATA_PIO_CSD);
126
        if (!(csd & BIT(7))) return 0;
127
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(0);
128
    }
129
}
130
 
131
static int ata_wait_for_rdy(long timeout)
132
{
133
    long startusec = USEC_TIMER;
134
    PASS_RC(ata_wait_for_not_bsy(timeout), 1, 0);
135
    while (true)
136
    {
137
        uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
138
        if (dad & BIT(6)) return 0;
139
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(1);
140
    }
141
}
142
 
143
static int ata_wait_for_start_of_transfer(long timeout)
144
{
145
    long startusec = USEC_TIMER;
146
    PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0);
147
    while (true)
148
    {
149
        uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
150
        if (dad & BIT(0)) RET_ERR(1);
151
        if ((dad & (BIT(7) | BIT(3))) == BIT(3)) return 0;
152
        if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(2);
153
    }
154
}
155
 
156
static int ata_wait_for_end_of_transfer(long timeout)
157
{
158
    PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0);
159
    uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
160
    if (dad & BIT(0)) RET_ERR(1);
161
    if ((dad & (BIT(3) | BITRANGE(5, 7))) == BIT(6)) return 0;
162
    RET_ERR(2);
163
}    
164
 
629 theseven 165
int mmc_dsta_check_command_success(bool disable_crc)
166
{
167
    int rc = 0;
168
    uint32_t dsta = SDCI_DSTA;
169
    if (dsta & SDCI_DSTA_RESTOUTE) rc |= 1; 
170
    if (dsta & SDCI_DSTA_RESENDE) rc |= 2;
171
    if (dsta & SDCI_DSTA_RESINDE) rc |= 4;
172
    if (!disable_crc)
173
        if (dsta & SDCI_DSTA_RESCRCE)
174
            rc |= 8;
175
    if (rc) RET_ERR(rc);
176
    return 0;
177
}
178
 
179
bool mmc_send_command(uint32_t cmd, uint32_t arg, uint32_t* result, int timeout)
180
{
181
    long starttime = USEC_TIMER;
182
    while ((SDCI_STATE & SDCI_STATE_CMD_STATE_MASK) != SDCI_STATE_CMD_STATE_CMD_IDLE)
183
    {
184
        if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(0);
185
        yield();
186
    }
187
    SDCI_STAC = SDCI_STAC_CLR_CMDEND | SDCI_STAC_CLR_BIT_3
188
              | SDCI_STAC_CLR_RESEND | SDCI_STAC_CLR_DATEND
189
              | SDCI_STAC_CLR_DAT_CRCEND | SDCI_STAC_CLR_CRC_STAEND
190
              | SDCI_STAC_CLR_RESTOUTE | SDCI_STAC_CLR_RESENDE
191
              | SDCI_STAC_CLR_RESINDE | SDCI_STAC_CLR_RESCRCE
192
              | SDCI_STAC_CLR_WR_DATCRCE | SDCI_STAC_CLR_RD_DATCRCE
193
              | SDCI_STAC_CLR_RD_DATENDE0 | SDCI_STAC_CLR_RD_DATENDE1
194
              | SDCI_STAC_CLR_RD_DATENDE2 | SDCI_STAC_CLR_RD_DATENDE3
195
              | SDCI_STAC_CLR_RD_DATENDE4 | SDCI_STAC_CLR_RD_DATENDE5
196
              | SDCI_STAC_CLR_RD_DATENDE6 | SDCI_STAC_CLR_RD_DATENDE7;
197
    SDCI_ARGU = arg;
198
    SDCI_CMD = cmd;
199
    if (!(SDCI_DSTA & SDCI_DSTA_CMDRDY)) RET_ERR(1);
200
    SDCI_CMD = cmd | SDCI_CMD_CMDSTR;
201
    sleep(1000);
202
    while (!(SDCI_DSTA & SDCI_DSTA_CMDEND))
203
    {
204
        if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(2);
205
        yield();
206
    }
207
    if ((cmd & SDCI_CMD_RES_TYPE_MASK) != SDCI_CMD_RES_TYPE_NONE)
208
    {
209
        while (!(SDCI_DSTA & SDCI_DSTA_RESEND))
210
        {
211
            if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(3);
212
            yield();
213
        }
214
        if (cmd & SDCI_CMD_RES_BUSY)
215
            while (SDCI_DSTA & SDCI_DSTA_DAT_BUSY)
216
            {
217
                if (TIMEOUT_EXPIRED(starttime, CEATA_DAT_NONBUSY_TIMEOUT)) RET_ERR(4);
218
                yield();
219
            }
220
    }
221
    bool nocrc = (cmd & SDCI_CMD_RES_SIZE_MASK) == SDCI_CMD_RES_SIZE_136;
222
    PASS_RC(mmc_dsta_check_command_success(nocrc), 3, 5);
223
    if (result) *result = SDCI_RESP0;
224
    return 0;
225
}
226
 
227
int mmc_get_card_status(uint32_t* result)
228
{
229
    return mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SEND_STATUS)
230
                          | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1
231
                          | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
232
                            MMC_CMD_SEND_STATUS_RCA(CEATA_MMC_RCA), result, CEATA_COMMAND_TIMEOUT);
233
}
234
 
235
int mmc_init()
236
{
237
    sleep(100000);
238
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_GO_IDLE_STATE)
239
                           | SDCI_CMD_CMD_TYPE_BC | SDCI_CMD_RES_TYPE_NONE
240
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NID,
241
                             0, NULL, CEATA_COMMAND_TIMEOUT), 3, 0);
242
    long startusec = USEC_TIMER;
243
    uint32_t result;
244
    do
245
    {
246
        if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) RET_ERR(1);
247
        sleep(1000);
248
        PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SEND_OP_COND)
249
                               | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R3
250
                               | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NID,
251
                                 MMC_CMD_SEND_OP_COND_OCR(MMC_OCR_270_360),
252
                                 NULL, CEATA_COMMAND_TIMEOUT), 3, 2);
253
        result = SDCI_RESP0;
254
    }
255
    while (!(result & MMC_OCR_POWER_UP_DONE));
256
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_ALL_SEND_CID)
257
                           | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R2
258
                           | SDCI_CMD_RES_SIZE_136 | SDCI_CMD_NCR_NID_NID,
259
                             0, NULL, CEATA_COMMAND_TIMEOUT), 3, 3);
260
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SET_RELATIVE_ADDR)
261
                           | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R1
262
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
263
                             MMC_CMD_SET_RELATIVE_ADDR_RCA(CEATA_MMC_RCA),
264
                             NULL, CEATA_COMMAND_TIMEOUT), 3, 4);
265
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SELECT_CARD)
266
                           | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1
267
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
268
                             MMC_CMD_SELECT_CARD_RCA(CEATA_MMC_RCA),
269
                             NULL, CEATA_COMMAND_TIMEOUT), 3, 5);
270
    PASS_RC(mmc_get_card_status(&result), 3, 6);
271
    if ((result & MMC_STATUS_CURRENT_STATE_MASK) != MMC_STATUS_CURRENT_STATE_TRAN) RET_ERR(7);
272
    return 0;
273
}
274
 
275
int mmc_fastio_write(uint32_t addr, uint32_t data)
276
{
277
    return mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_FAST_IO)
278
                          | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R4
279
                          | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
280
                            MMC_CMD_FAST_IO_RCA(CEATA_MMC_RCA) | MMC_CMD_FAST_IO_DIRECTION_WRITE
281
                          | MMC_CMD_FAST_IO_ADDRESS(addr) | MMC_CMD_FAST_IO_DATA(data),
282
                            NULL, CEATA_COMMAND_TIMEOUT);
283
}
284
 
285
int mmc_fastio_read(uint32_t addr, uint32_t* data)
286
{
287
    return mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_FAST_IO)
288
                          | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R4
289
                          | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
290
                            MMC_CMD_FAST_IO_RCA(CEATA_MMC_RCA) | MMC_CMD_FAST_IO_DIRECTION_READ
291
                          | MMC_CMD_FAST_IO_ADDRESS(addr), data, CEATA_COMMAND_TIMEOUT);
292
}
293
 
294
int ceata_soft_reset()
295
{
296
    PASS_RC(mmc_fastio_write(6, 4), 2, 0);
297
    sleep(1000);
298
    PASS_RC(mmc_fastio_write(6, 0), 2, 1);
299
    sleep(10000);
300
    long startusec = USEC_TIMER;
301
    uint32_t status;
302
    do
303
    {
304
        PASS_RC(mmc_fastio_read(0xf, &status), 2, 2);
305
        if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) RET_ERR(3);
306
        sleep(1000);
307
    }
308
    while (status & 0x80);
309
    return 0;
310
}
311
 
312
int mmc_dsta_check_data_success()
313
{
314
    int rc = 0;
315
    uint32_t dsta = SDCI_DSTA;
316
    if (dsta & (SDCI_DSTA_WR_DATCRCE | SDCI_DSTA_RD_DATCRCE))
317
    {
318
        if (dsta & SDCI_DSTA_WR_DATCRCE) rc |= 1;
319
        if (dsta & SDCI_DSTA_RD_DATCRCE) rc |= 2;
320
        if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_TXERR) rc |= 4;
321
        else if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_CARDERR) rc |= 8;
322
    }
323
    if (dsta & (SDCI_DSTA_RD_DATENDE0 | SDCI_DSTA_RD_DATENDE1 | SDCI_DSTA_RD_DATENDE2
324
              | SDCI_DSTA_RD_DATENDE3 | SDCI_DSTA_RD_DATENDE4 | SDCI_DSTA_RD_DATENDE5
325
              | SDCI_DSTA_RD_DATENDE6 | SDCI_DSTA_RD_DATENDE7))
326
        rc |= 16;
327
    if (rc) RET_ERR(rc);
328
    return 0;
329
}
330
 
331
void mmc_discard_irq()
332
{
333
    SDCI_IRQ = SDCI_IRQ_DAT_DONE_INT | SDCI_IRQ_MASK_MASK_IOCARD_IRQ_INT
334
             | SDCI_IRQ_MASK_MASK_READ_WAIT_INT;
335
    wakeup_wait(&mmc_wakeup, TIMEOUT_NONE);
336
}
337
 
338
int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size)
339
{
340
    if (size > 0x10) RET_ERR(0);
341
    mmc_discard_irq();
342
    SDCI_DMASIZE = size;
343
    SDCI_DMACOUNT = 1;
344
    SDCI_DMAADDR = dest;
345
    SDCI_DCTRL = SDCI_DCTRL_TXFIFORST | SDCI_DCTRL_RXFIFORST;
346
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_CEATA_RW_MULTIPLE_REG)
347
                           | SDCI_CMD_CMD_TYPE_ADTC | SDCI_CMD_RES_TYPE_R1
348
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
349
                             MMC_CMD_CEATA_RW_MULTIPLE_REG_DIRECTION_READ
350
                           | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc)
351
                           | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc),
352
                             NULL, CEATA_COMMAND_TIMEOUT), 2, 1);
353
    long startusec = USEC_TIMER;
354
    if (wakeup_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT) == THREAD_TIMEOUT) RET_ERR(2);
355
    invalidate_dcache();
356
    PASS_RC(mmc_dsta_check_data_success(), 2, 3);
357
    return 0;
358
}
359
 
360
int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t size)
361
{
362
    int i;
363
    if (size > 0x10) RET_ERR(0);
364
    mmc_discard_irq();
365
    SDCI_DMASIZE = size;
366
    SDCI_DMACOUNT = 0;
367
    SDCI_DCTRL = SDCI_DCTRL_TXFIFORST | SDCI_DCTRL_RXFIFORST;
368
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_CEATA_RW_MULTIPLE_REG)
369
                           | SDCI_CMD_CMD_TYPE_ADTC | SDCI_CMD_CMD_RD_WR
370
                           | SDCI_CMD_RES_BUSY | SDCI_CMD_RES_TYPE_R1
371
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
372
                             MMC_CMD_CEATA_RW_MULTIPLE_REG_DIRECTION_WRITE
373
                           | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc)
374
                           | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc),
375
                             NULL, CEATA_COMMAND_TIMEOUT), 3, 1);
376
    SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX;
377
    for (i = 0; i < size / 4; i++) SDCI_DATA = ((uint32_t*)dest)[i];
378
    long startusec = USEC_TIMER;
379
    if (wakeup_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT) == THREAD_TIMEOUT) RET_ERR(2);
380
    while ((SDCI_STATE & SDCI_STATE_DAT_STATE_MASK) != SDCI_STATE_DAT_STATE_IDLE)
381
    {
382
        if (TIMEOUT_EXPIRED(startusec, CEATA_COMMAND_TIMEOUT)) RET_ERR(3);
383
        yield();
384
    }
385
    PASS_RC(mmc_dsta_check_data_success(), 3, 4);
386
    return 0;
387
}
388
 
389
int ceata_init(int buswidth)
390
{
391
    uint32_t result;
392
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SWITCH) | SDCI_CMD_RES_BUSY
393
                           | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1 
394
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
395
                             MMC_CMD_SWITCH_ACCESS_WRITE_BYTE
396
                           | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_HS_TIMING)
397
                           | MMC_CMD_SWITCH_VALUE(MMC_CMD_SWITCH_FIELD_HS_TIMING_HIGH_SPEED),
398
                             &result, CEATA_COMMAND_TIMEOUT), 3, 0);
399
    if (result & MMC_STATUS_SWITCH_ERROR) RET_ERR(1);
400
    if (buswidth > 1)
401
    {
402
        int setting;
403
        if (buswidth == 4) setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_4BIT;
404
        else if (buswidth == 8) setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_8BIT;
405
        else setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_1BIT;
406
        PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SWITCH) | SDCI_CMD_RES_BUSY
407
                               | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1
408
                               | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
409
                                 MMC_CMD_SWITCH_ACCESS_WRITE_BYTE
410
                               | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_BUS_WIDTH)
411
                               | MMC_CMD_SWITCH_VALUE(setting),
412
                                 &result, CEATA_COMMAND_TIMEOUT), 3, 2);
413
        if (result & MMC_STATUS_SWITCH_ERROR) RET_ERR(3);
414
        if (buswidth == 4)
415
            SDCI_CTRL = (SDCI_CTRL & ~SDCI_CTRL_BUS_WIDTH_MASK) | SDCI_CTRL_BUS_WIDTH_4BIT;
416
        else if (buswidth == 8)
417
            SDCI_CTRL = (SDCI_CTRL & ~SDCI_CTRL_BUS_WIDTH_MASK) | SDCI_CTRL_BUS_WIDTH_8BIT;
418
    }
419
    PASS_RC(ceata_soft_reset(), 3, 4);
420
    PASS_RC(ceata_read_multiple_register(0, ceata_taskfile, 0x10), 3, 5);
421
    if (ceata_taskfile[0xc] != 0xce || ceata_taskfile[0xd] != 0xaa) RET_ERR(6);
422
    PASS_RC(mmc_fastio_write(6, 0), 3, 7);
423
    return 0;
424
}
425
 
426
int ceata_check_error()
427
{
428
    uint32_t status, error;
429
    PASS_RC(mmc_fastio_read(0xf, &status), 2, 0);
430
    if (status & 1)
431
    {
432
        PASS_RC(mmc_fastio_read(0x9, &error), 2, 1);
433
        RET_ERR((error << 2) | 2);
434
    }
435
    return 0;
436
}
437
 
438
int ceata_wait_idle()
439
{
440
    long startusec = USEC_TIMER;
441
    while (true)
442
    {
443
        uint32_t status;
444
        PASS_RC(mmc_fastio_read(0xf, &status), 1, 0);
445
        if (!(status & 0x88)) return 0;
446
        if (TIMEOUT_EXPIRED(startusec, CEATA_DAT_NONBUSY_TIMEOUT)) RET_ERR(1);
447
        sleep(50000);
448
    }
449
}
450
 
451
int ceata_cancel_command()
452
{
453
    *((uint32_t volatile*)0x3cf00200) = 0x9000e;
454
    sleep(1);
455
    *((uint32_t volatile*)0x3cf00200) = 0x9000f;
456
    sleep(1);
457
    *((uint32_t volatile*)0x3cf00200) = 0x90003;
458
    sleep(1);
459
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_STOP_TRANSMISSION)
460
                           | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1 | SDCI_CMD_RES_BUSY
461
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
462
                             0, NULL, CEATA_COMMAND_TIMEOUT), 1, 0);
463
    PASS_RC(ceata_wait_idle(), 1, 1);
464
    return 0;
465
}
466
 
467
int ceata_rw_multiple_block(bool write, void* buf, uint32_t count, long timeout)
468
{
469
    mmc_discard_irq();
470
    uint32_t responsetype;
471
    uint32_t cmdtype;
472
    uint32_t direction;
473
    if (write)
474
    {
475
        clean_dcache();
476
        cmdtype = SDCI_CMD_CMD_TYPE_ADTC | SDCI_CMD_CMD_RD_WR;
477
        responsetype = SDCI_CMD_RES_TYPE_R1 | SDCI_CMD_RES_BUSY;
478
        direction = MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_DIRECTION_WRITE;
479
    }
480
    else
481
    {
482
        cmdtype = SDCI_CMD_CMD_TYPE_ADTC;
483
        responsetype = SDCI_CMD_RES_TYPE_R1;
484
        direction = MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_DIRECTION_READ;
485
    }
486
    SDCI_DMASIZE = 0x200;
487
    SDCI_DMAADDR = buf;
488
    SDCI_DMACOUNT = count;
489
    SDCI_DCTRL = SDCI_DCTRL_TXFIFORST | SDCI_DCTRL_RXFIFORST;
490
    PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_CEATA_RW_MULTIPLE_BLOCK)
491
                           | SDCI_CMD_CMD_TYPE_ADTC | cmdtype | responsetype
492
                           | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
493
                             direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count),
494
                             NULL, CEATA_COMMAND_TIMEOUT), 4, 0);
495
    if (write) SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX;
496
    if (wakeup_wait(&mmc_wakeup, timeout) == THREAD_TIMEOUT)
497
    {
498
        PASS_RC(ceata_cancel_command(), 4, 1);
499
        RET_ERR(2);
500
    }
501
    if (!write) invalidate_dcache();
502
    PASS_RC(mmc_dsta_check_data_success(), 4, 3);
503
    if (wakeup_wait(&mmc_comp_wakeup, timeout) == THREAD_TIMEOUT)
504
    {
505
        PASS_RC(ceata_cancel_command(), 4, 4);
506
        RET_ERR(4);
507
    }
508
    PASS_RC(ceata_check_error(), 4, 5);
509
    return 0;
510
}
511
 
301 theseven 512
int ata_identify(uint16_t* buf)
513
{
514
    int i;
629 theseven 515
    if (ceata)
301 theseven 516
    {
629 theseven 517
        memset(ceata_taskfile, 0, 16);
518
        ceata_taskfile[0xf] = 0xec;
519
        PASS_RC(ceata_wait_idle(), 2, 0);
520
        PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1);
521
        PASS_RC(ceata_rw_multiple_block(false, buf, 1, CEATA_COMMAND_TIMEOUT), 2, 2);
522
        for (i = 0; i < 0x100; i++)
523
        {
524
            uint16_t word = buf[i];
525
            buf[i] = (word >> 8) | (word << 8);
526
        }
301 theseven 527
    }
629 theseven 528
    else
529
    {
530
        PASS_RC(ata_wait_for_not_bsy(10000000), 1, 0);
531
        ata_write_cbr(&ATA_PIO_DVR, 0);
532
        ata_write_cbr(&ATA_PIO_CSD, 0xec);
533
        PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1);
534
        for (i = 0; i < 0x100; i++)
535
        {
536
            uint16_t word = ata_read_cbr(&ATA_PIO_DTR);
537
            buf[i] = (word >> 8) | (word << 8);
538
        }
539
    }
540
    return 0;
301 theseven 541
}
542
 
543
void ata_set_active(void)
544
{
545
    ata_last_activity_value = USEC_TIMER;
546
}
547
 
620 theseven 548
bool ata_disk_is_active(void)
549
{
550
    return ata_powered;
551
}
552
 
553
int ata_num_drives(void)
554
{
555
    return 1;
556
}
557
 
317 theseven 558
int ata_set_feature(uint32_t feature, uint32_t param)
559
{
560
    PASS_RC(ata_wait_for_rdy(500000), 1, 0);
561
    ata_write_cbr(&ATA_PIO_DVR, 0);
562
    ata_write_cbr(&ATA_PIO_FED, 3);
563
    ata_write_cbr(&ATA_PIO_SCR, param);
564
    ata_write_cbr(&ATA_PIO_CSD, feature);
565
    PASS_RC(ata_wait_for_rdy(500000), 1, 1);
566
    return 0;
567
}
568
 
301 theseven 569
int ata_power_up()
570
{
571
    ata_set_active();
357 theseven 572
    if (ata_powered) return 0;
301 theseven 573
    i2c_sendbyte(0, 0xe6, 0x1b, 1);
629 theseven 574
    if (ceata)
301 theseven 575
    {
629 theseven 576
        clockgate_enable(9, true);
577
        SDCI_RESET = 0xa5;
578
        sleep(1000);
579
        *((uint32_t volatile*)0x3cf00380) = 0;
580
        *((uint32_t volatile*)0x3cf0010c) = 0xff;
581
        SDCI_CTRL = SDCI_CTRL_SDCIEN | SDCI_CTRL_CLK_SEL_SDCLK
582
                  | SDCI_CTRL_BIT_8 | SDCI_CTRL_BIT_14;
583
        SDCI_CDIV = SDCI_CDIV_CLKDIV(260);
584
        *((uint32_t volatile*)0x3cf00200) = 0xb000f;
585
        SDCI_IRQ_MASK = SDCI_IRQ_MASK_MASK_DAT_DONE_INT | SDCI_IRQ_MASK_MASK_IOCARD_IRQ_INT;
586
        PASS_RC(mmc_init(), 2, 0);
587
        SDCI_CDIV = SDCI_CDIV_CLKDIV(4);
588
        sleep(10000);
589
        PASS_RC(ceata_init(8), 2, 1);
590
        PASS_RC(ata_identify(ata_identify_data), 2, 2);
301 theseven 591
    }
629 theseven 592
    else
301 theseven 593
    {
629 theseven 594
        clockgate_enable(5, true);
595
        ATA_CFG = BIT(0);
596
        sleep(1000);
597
        ATA_CFG = 0;
598
        sleep(6000);
599
        ATA_SWRST = BIT(0);
600
        sleep(500);
601
        ATA_SWRST = 0;
602
        sleep(90000);
603
        ATA_CONTROL = BIT(0);
604
        sleep(200000);
605
        ATA_PIO_TIME = 0x191f7;
606
        ATA_PIO_LHR = 0;
607
        while (!(ATA_PIO_READY & BIT(1))) sleep(100);
608
        PASS_RC(ata_identify(ata_identify_data), 2, 0);
609
        uint32_t piotime = 0x11f3;
610
        uint32_t mdmatime = 0x1c175;
611
        uint32_t udmatime = 0x5071152;
612
        uint32_t param = 0;
613
        ata_dma_flags = 0;
614
        ata_lba48 = ata_identify_data[83] & BIT(10) ? true : false;
615
        if (ata_identify_data[53] & BIT(1))
301 theseven 616
        {
629 theseven 617
            if (ata_identify_data[64] & BIT(1)) piotime = 0x2072;
618
            else if (ata_identify_data[64] & BIT(0)) piotime = 0x7083;
301 theseven 619
        }
629 theseven 620
        if (ata_identify_data[63] & BIT(2))
301 theseven 621
        {
629 theseven 622
            mdmatime = 0x5072;
623
            param = 0x22;
301 theseven 624
        }
629 theseven 625
        else if (ata_identify_data[63] & BIT(1))
301 theseven 626
        {
629 theseven 627
            mdmatime = 0x7083;
628
            param = 0x21;
301 theseven 629
        }
629 theseven 630
        if (ata_identify_data[63] & BITRANGE(0, 2))
301 theseven 631
        {
629 theseven 632
            ata_dma_flags = BIT(3) | BIT(10);
633
            param |= 0x20;
301 theseven 634
        }
629 theseven 635
        if (ata_identify_data[53] & BIT(2))
301 theseven 636
        {
629 theseven 637
            if (ata_identify_data[88] & BIT(4))
638
            {
639
                udmatime = 0x2010a52;
640
                param = 0x44;
641
            }
642
            else if (ata_identify_data[88] & BIT(3))
643
            {
644
                udmatime = 0x2020a52;
645
                param = 0x43;
646
            }
647
            else if (ata_identify_data[88] & BIT(2))
648
            {
649
                udmatime = 0x3030a52;
650
                param = 0x42;
651
            }
652
            else if (ata_identify_data[88] & BIT(1))
653
            {
654
                udmatime = 0x3050a52;
655
                param = 0x41;
656
            }
657
            if (ata_identify_data[88] & BITRANGE(0, 4))
658
            {
659
                ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10);
660
                param |= 0x40;
661
            }
301 theseven 662
        }
629 theseven 663
        ata_dma = param ? true : false;
664
        PASS_RC(ata_set_feature(0xef, param), 2, 1);
665
        if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x02, 0), 2, 2);
666
        if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0x55, 0), 2, 3);
667
        ATA_PIO_TIME = piotime;
668
        ATA_MDMA_TIME = mdmatime;
669
        ATA_UDMA_TIME = udmatime;
301 theseven 670
    }
629 theseven 671
    if (ata_lba48)
672
        ata_total_sectors = ata_identify_data[100]
673
                            | (((uint64_t)ata_identify_data[101]) << 16)
674
                            | (((uint64_t)ata_identify_data[102]) << 32)
675
                            | (((uint64_t)ata_identify_data[103]) << 48);
676
    else ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16);
677
    ata_total_sectors >>= 3;
301 theseven 678
    ata_powered = true;
679
    ata_set_active();
680
    return 0;
681
}
682
 
683
void ata_power_down()
684
{
357 theseven 685
    if (!ata_powered) return;
301 theseven 686
    ata_powered = false;
629 theseven 687
    if (ceata)
688
    {
689
        memset(ceata_taskfile, 0, 16);
690
        ceata_taskfile[0xf] = 0xe0;
691
        ceata_wait_idle();
692
        ceata_write_multiple_register(0, ceata_taskfile, 16);
693
        wakeup_wait(&mmc_comp_wakeup, CEATA_COMMAND_TIMEOUT);
694
        sleep(30000);
695
        clockgate_enable(9, false);
696
    }
697
    else
698
    {
699
        ata_wait_for_rdy(1000000);
700
        ata_write_cbr(&ATA_PIO_DVR, 0);
701
        ata_write_cbr(&ATA_PIO_CSD, 0xe0);
702
        ata_wait_for_rdy(1000000);
703
        sleep(30000);
704
        ATA_CONTROL = 0;
705
        while (!(ATA_CONTROL & BIT(1))) yield();
706
        clockgate_enable(5, false);
707
    }
301 theseven 708
    i2c_sendbyte(0, 0xe6, 0x1b, 0);
709
}
710
 
337 theseven 711
int ata_rw_chunk(uint64_t sector, uint32_t cnt, void* buffer, bool write)
712
{
629 theseven 713
    if (ceata)
337 theseven 714
    {
629 theseven 715
        memset(ceata_taskfile, 0, 16);
716
        ceata_taskfile[0x2] = cnt >> 5;
717
        ceata_taskfile[0x3] = sector >> 21;
718
        ceata_taskfile[0x4] = sector >> 29;
719
        ceata_taskfile[0x5] = sector >> 37;
720
        ceata_taskfile[0xa] = cnt << 3;
721
        ceata_taskfile[0xb] = sector << 3;
722
        ceata_taskfile[0xc] = sector >> 5;
723
        ceata_taskfile[0xd] = sector >> 13;
724
        ceata_taskfile[0xf] = write ? 0x35 : 0x25;
725
        PASS_RC(ceata_wait_idle(), 2, 0);
726
        PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1);
727
        PASS_RC(ceata_rw_multiple_block(write, buffer, cnt, CEATA_COMMAND_TIMEOUT), 2, 2);
337 theseven 728
    }
729
    else
730
    {
629 theseven 731
        PASS_RC(ata_wait_for_rdy(100000), 2, 0);
732
        ata_write_cbr(&ATA_PIO_DVR, 0);
733
        if (ata_lba48)
337 theseven 734
        {
629 theseven 735
            ata_write_cbr(&ATA_PIO_SCR, cnt >> 5);
736
            ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
737
            ata_write_cbr(&ATA_PIO_LHR, (sector >> 37) & 0xff);
738
            ata_write_cbr(&ATA_PIO_LMR, (sector >> 29) & 0xff);
739
            ata_write_cbr(&ATA_PIO_LLR, (sector >> 21) & 0xff);
740
            ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
741
            ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
742
            ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
743
            ata_write_cbr(&ATA_PIO_DVR, BIT(6));
744
            if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x35 : 0x39);
745
            else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0x25 : 0x29);
337 theseven 746
        }
747
        else
748
        {
629 theseven 749
            ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff);
750
            ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff);
751
            ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff);
752
            ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff);
753
            ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 21) & 0xf));
754
            if (write) ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xca : 0x30);
755
            else ata_write_cbr(&ATA_PIO_CSD, ata_dma ? 0xc8 : 0xc4);
337 theseven 756
        }
629 theseven 757
        if (ata_dma)
337 theseven 758
        {
629 theseven 759
            PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
760
            if (write)
761
            {
762
                ATA_SBUF_START = buffer;
763
                ATA_SBUF_SIZE = SECTOR_SIZE * cnt;
764
                ATA_CFG |= BIT(4);
765
            }
766
            else
767
            {
768
                ATA_TBUF_START = buffer;
769
                ATA_TBUF_SIZE = SECTOR_SIZE * cnt;
770
                ATA_CFG &= ~BIT(4);
771
            }
772
            ATA_XFR_NUM = SECTOR_SIZE * cnt - 1;
773
            ATA_CFG |= ata_dma_flags;
774
            ATA_CFG &= ~(BIT(7) | BIT(8));
775
            wakeup_wait(&ata_wakeup, TIMEOUT_NONE);
776
            ATA_IRQ = BITRANGE(0, 4);
777
            ATA_IRQ_MASK = BIT(0);
778
            ATA_COMMAND = BIT(0);
779
            if (wakeup_wait(&ata_wakeup, 500000) == THREAD_TIMEOUT)
780
            {
781
                ATA_COMMAND = BIT(1);
782
                ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
783
                RET_ERR(2);
784
            }
337 theseven 785
            ATA_COMMAND = BIT(1);
786
            ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
787
        }
629 theseven 788
        else
337 theseven 789
        {
629 theseven 790
            cnt *= SECTOR_SIZE / 512;
791
            while (cnt--)
792
            {
793
                int i;
794
                PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
795
                if (write)
796
                    for (i = 0; i < 256; i++)
797
                        ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]);
798
                else
799
                    for (i = 0; i < 256; i++)
800
                        ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR);
801
                buffer += 512;
802
            }
337 theseven 803
        }
629 theseven 804
        PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3);
337 theseven 805
    }
806
    return 0;
807
}
808
 
613 theseven 809
#ifdef ATA_HAVE_BBT
810
int ata_bbt_translate(uint64_t sector, uint32_t count, uint64_t* phys, uint32_t* physcount)
811
{
812
    if (sector + count > ata_virtual_sectors) RET_ERR(0);
813
    if (!ata_bbt)
814
    {
815
        *phys = sector;
816
        *physcount = count;
817
        return 0;
818
    }
819
    if (!count)
820
    {
821
        *phys = 0;
822
        *physcount = 0;
823
        return 0;
824
    }
825
    uint32_t offset;
826
    uint32_t l0idx = sector >> 15;
827
    uint32_t l0offs = sector & 0x7fff;
828
    *physcount = MIN(count, 0x8000 - l0offs);
829
    uint32_t l0data = ata_bbt[0][l0idx << 1];
830
    uint32_t base = ata_bbt[0][(l0idx << 1) | 1] << 12;
831
    if (l0data < 0x8000) offset = l0data + base;
832
    else
833
    {
834
        uint32_t l1idx = (sector >> 10) & 0x1f;
835
        uint32_t l1offs = sector & 0x3ff;
836
        *physcount = MIN(count, 0x400 - l1offs);
837
        uint32_t l1data = ata_bbt[l0data & 0x7fff][l1idx];
838
        if (l1data < 0x8000) offset = l1data + base;
839
        else
840
        {
841
            uint32_t l2idx = (sector >> 5) & 0x1f;
842
            uint32_t l2offs = sector & 0x1f;
843
            *physcount = MIN(count, 0x20 - l2offs);
844
            uint32_t l2data = ata_bbt[l1data & 0x7fff][l2idx];
845
            if (l2data < 0x8000) offset = l2data + base;
846
            else
847
            {
848
                uint32_t l3idx = sector & 0x1f;
849
                uint32_t l3data = ata_bbt[l2data & 0x7fff][l3idx];
850
                for (*physcount = 1; *physcount < count && l3idx + *physcount < 0x20; *physcount++)
851
                    if (ata_bbt[l2data & 0x7fff][l3idx + *physcount] != l3data)
852
                        break;
853
                offset = l3data + base;
854
            }
855
        }
856
    }
857
    *phys = sector + offset;
858
    return 0;
859
}
860
#endif
861
 
301 theseven 862
int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write)
863
{
627 theseven 864
    if (((uint32_t)buffer) & (CACHEALIGN_SIZE - 1))
865
        panicf(PANIC_KILLTHREAD,
866
               "ATA: Misaligned data buffer at %08X (sector %lu, count %lu)",
867
               (unsigned int)buffer, (unsigned int)sector, count);
328 theseven 868
#ifdef ATA_HAVE_BBT
869
    if (sector + count > ata_virtual_sectors) RET_ERR(0);
430 theseven 870
    if (ata_bbt)
871
        while (count)
328 theseven 872
        {
613 theseven 873
            uint64_t phys;
874
            uint32_t cnt;
875
            PASS_RC(ata_bbt_translate(sector, count, &phys, &cnt), 0, 0);
876
            uint32_t offset = phys - sector;
430 theseven 877
            if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_soft_reset();
878
            ata_last_offset = offset;
879
            ata_last_phys = phys + cnt;
880
            PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0);
881
            buffer += cnt * SECTOR_SIZE;
882
            sector += cnt;
883
            count -= cnt;
328 theseven 884
        }
430 theseven 885
    else PASS_RC(ata_rw_sectors_internal(sector, count, buffer, write), 0, 0);
328 theseven 886
    return 0;
887
}
888
 
889
int ata_rw_sectors_internal(uint64_t sector, uint32_t count, void* buffer, bool write)
890
{
891
#endif
301 theseven 892
    if (sector + count > ata_total_sectors) RET_ERR(0);
893
    if (!ata_powered) ata_power_up();
894
    ata_set_active();
895
    if (ata_dma && write) clean_dcache();
896
    else if (ata_dma) invalidate_dcache();
629 theseven 897
    if (!ceata) ATA_COMMAND = BIT(1);
301 theseven 898
    while (count)
899
    {
317 theseven 900
        uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count);
337 theseven 901
        int rc = -1;
613 theseven 902
        rc = ata_rw_chunk(sector, cnt, buffer, write);
620 theseven 903
        if (rc && ata_error_srst) ata_soft_reset();
904
        if (rc && ata_retries)
301 theseven 905
        {
337 theseven 906
            void* buf = buffer;
405 theseven 907
            uint64_t sect;
337 theseven 908
            for (sect = sector; sect < sector + cnt; sect++)
909
            {
910
                rc = -1;
620 theseven 911
                int tries = ata_retries;
337 theseven 912
                while (tries-- && rc)
913
                {
914
                    rc = ata_rw_chunk(sect, 1, buf, write);
620 theseven 915
                    if (rc && ata_error_srst) ata_soft_reset();
337 theseven 916
                }
917
                if (rc) break;
918
                buf += SECTOR_SIZE;
919
            }
301 theseven 920
        }
337 theseven 921
        PASS_RC(rc, 1, 1);
922
        buffer += SECTOR_SIZE * cnt;
301 theseven 923
        sector += cnt;
924
        count -= cnt;
925
    }
926
    ata_set_active();
927
    return 0;
928
}
929
 
930
static void ata_thread(void)
931
{
932
    while (true)
933
    {
934
        mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
935
        if (TIME_AFTER(USEC_TIMER, ata_last_activity_value + ata_sleep_timeout) && ata_powered)
936
            ata_power_down();
937
        mutex_unlock(&ata_mutex);
938
        sleep(1000000);
939
    }
940
}
941
 
942
/* API Functions */
943
int ata_soft_reset()
944
{
629 theseven 945
    int rc;
301 theseven 946
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
947
    if (!ata_powered) ata_power_up();
948
    ata_set_active();
629 theseven 949
    if (ceata) rc = ceata_soft_reset();
950
    else
951
    {
952
        ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2));
953
        sleep(10);
954
        ata_write_cbr(&ATA_PIO_DAD, 0);
955
        rc = ata_wait_for_rdy(20000000);
956
    }
613 theseven 957
    if (IS_ERR(rc))
958
    {
959
        ata_power_down();
960
        sleep(3000000);
961
        ata_power_up();
962
    }
301 theseven 963
    ata_set_active();
964
    mutex_unlock(&ata_mutex);
620 theseven 965
    return rc;
301 theseven 966
}
967
 
968
int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
969
                     void* inbuf)
970
{
971
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
337 theseven 972
    int rc = ata_rw_sectors(start, incount, inbuf, false);
301 theseven 973
    mutex_unlock(&ata_mutex);
974
    return rc;
975
}
976
 
977
int ata_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
978
                      const void* outbuf)
979
{
980
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
337 theseven 981
    int rc = ata_rw_sectors(start, count, (void*)((uint32_t)outbuf), true);
301 theseven 982
    mutex_unlock(&ata_mutex);
983
    return rc;
984
}
985
 
337 theseven 986
void ata_spindown(int seconds)
987
{
988
    ata_sleep_timeout = seconds * 1000000;
989
}
301 theseven 990
 
991
void ata_sleep(void)
992
{
993
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
994
    ata_power_down();
995
    mutex_unlock(&ata_mutex);
996
}
997
 
998
void ata_sleepnow(void)
999
{
1000
    ata_sleep();
1001
}
1002
 
1003
void ata_close(void)
1004
{
1005
    ata_sleep();
1006
}
1007
 
1008
void ata_spin(void)
1009
{
1010
    ata_power_up();
1011
}
1012
 
1013
void ata_get_info(IF_MD2(int drive,) struct storage_info *info)
1014
{
1015
    (*info).sector_size = SECTOR_SIZE;
328 theseven 1016
#ifdef ATA_HAVE_BBT
1017
    (*info).num_sectors = ata_virtual_sectors;
1018
#else
301 theseven 1019
    (*info).num_sectors = ata_total_sectors;
328 theseven 1020
#endif
301 theseven 1021
    (*info).vendor = "Apple";
1022
    (*info).product = "iPod Classic";
1023
    (*info).revision = "1.0";
613 theseven 1024
    (*info).driverinfo = &drvinfo;
301 theseven 1025
}
1026
 
1027
long ata_last_disk_activity(void)
1028
{
1029
    return ata_last_activity_value;
1030
}
1031
 
613 theseven 1032
#ifdef ATA_HAVE_BBT
1033
void ata_bbt_disable()
301 theseven 1034
{
328 theseven 1035
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
613 theseven 1036
    if (ata_bbt) free(ata_bbt);
430 theseven 1037
    ata_bbt = NULL;
613 theseven 1038
    ata_virtual_sectors = ata_total_sectors;
1039
    mutex_unlock(&ata_mutex);
1040
}
1041
 
1042
void ata_bbt_reload()
1043
{
1044
    mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
1045
    ata_bbt_disable();
328 theseven 1046
    ata_power_up();
430 theseven 1047
    uint32_t* buf = (uint32_t*)memalign(0x10, 0x1000);
1048
    if (buf)
328 theseven 1049
    {
620 theseven 1050
        if (IS_ERR(ata_bbt_read_sectors(0, 1, buf)))
1051
            ata_virtual_sectors = ata_total_sectors;
1052
        else if (!memcmp(buf, "emBIbbth", 8))
328 theseven 1053
        {
430 theseven 1054
            ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc];
1055
            uint32_t count = buf[0x1ff];
1056
            ata_bbt = (typeof(ata_bbt))memalign(0x10, 0x1000 * count);
620 theseven 1057
            if (!ata_bbt)
430 theseven 1058
            {
620 theseven 1059
                cprintf(CONSOLE_BOOT, "ATA: Failed to allocate memory for BBT! (%d bytes)",
1060
                        0x1000 * count);
1061
                ata_virtual_sectors = ata_total_sectors;
1062
            }
1063
            else
1064
            {
1065
                uint32_t i;
1066
                uint32_t cnt;
1067
                for (i = 0; i < count; i += cnt)
1068
                {
1069
                    uint32_t phys = buf[0x200 + i];
1070
                    for (cnt = 1; cnt < count; cnt++)
1071
                        if (buf[0x200 + i + cnt] != phys + cnt)
1072
                            break;
1073
                    if (IS_ERR(ata_bbt_read_sectors(phys, cnt, ata_bbt[i << 6])))
1074
                    {
1075
                        free(ata_bbt);
1076
                        ata_virtual_sectors = ata_total_sectors;
430 theseven 1077
                        break;
620 theseven 1078
                    }
1079
                }
1080
                if (ata_bbt) reownalloc(ata_bbt, NULL);
430 theseven 1081
            }
328 theseven 1082
        }
430 theseven 1083
        else ata_virtual_sectors = ata_total_sectors;
1084
        free(buf);
328 theseven 1085
    }
437 theseven 1086
    else ata_virtual_sectors = ata_total_sectors;
328 theseven 1087
    mutex_unlock(&ata_mutex);
613 theseven 1088
}
328 theseven 1089
#endif
613 theseven 1090
 
1091
int ata_init(void)
1092
{
1093
    mutex_init(&ata_mutex);
1094
    wakeup_init(&ata_wakeup);
629 theseven 1095
    wakeup_init(&mmc_wakeup);
1096
    wakeup_init(&mmc_comp_wakeup);
1097
    ceata = PDAT(11) & BIT(1);
1098
    if (ceata)
1099
    {
1100
        ata_lba48 = true;
1101
        ata_dma = true;
1102
        PCON(8) = 0x33333333;
1103
        PCON(9) = (PCON(9) & ~0xff) | 0x33;
1104
        PCON(11) |= 0xf;
1105
        *((uint32_t volatile*)0x38a00000) = 0;
1106
        *((uint32_t volatile*)0x38700000) = 0;
1107
    }
1108
    else
1109
    {
1110
        PCON(7) = 0x44444444;
1111
        PCON(8) = 0x44444444;
1112
        PCON(9) = 0x44444444;
1113
        PCON(10) = (PCON(10) & ~0xffff) | 0x4444;
1114
    }
613 theseven 1115
    ata_powered = false;
1116
    ata_total_sectors = 0;
1117
#ifdef ATA_HAVE_BBT
1118
    ata_bbt_reload();
1119
#endif
429 theseven 1120
    thread_create(&ata_thread_handle, "ATA idle monitor", ata_thread, ata_stack,
543 theseven 1121
                  sizeof(ata_stack), OS_THREAD, 1, true);
301 theseven 1122
    return 0;
1123
}
1124
 
1125
#ifdef CONFIG_STORAGE_MULTI
1126
int ata_num_drives(int first_drive)
1127
{
1128
    /* We don't care which logical drive number(s) we have been assigned */
1129
    (void)first_drive;
1130
 
1131
    return 1;
1132
}
1133
#endif
1134
 
1135
void INT_ATA()
1136
{
1137
    uint32_t ata_irq = ATA_IRQ;
1138
    ATA_IRQ = ata_irq;
1139
    if (ata_irq & ATA_IRQ_MASK) wakeup_signal(&ata_wakeup);
1140
    ATA_IRQ_MASK = 0;
1141
}
629 theseven 1142
 
1143
void INT_MMC()
1144
{
1145
    uint32_t irq = SDCI_IRQ;
1146
    if (irq & SDCI_IRQ_DAT_DONE_INT) wakeup_signal(&mmc_wakeup);
1147
    if (irq & SDCI_IRQ_IOCARD_IRQ_INT) wakeup_signal(&mmc_comp_wakeup);
1148
    SDCI_IRQ = irq;
1149
}