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