sdhc seems to work now :>

This commit is contained in:
Sven Peter 2009-04-12 16:41:21 +02:00 committed by bushing
parent 5ba315148b
commit b84f393c92
2 changed files with 14 additions and 25 deletions

21
sdhc.c
View File

@ -675,7 +675,7 @@ sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
* If the command has data to transfer in any direction, * If the command has data to transfer in any direction,
* execute the transfer now. * execute the transfer now.
*/ */
if (cmd->c_error == 0 && cmd->c_data != NULL) if (cmd->c_error == 0 && cmd->c_datalen > 0)
sdhc_transfer_data(hp, cmd); sdhc_transfer_data(hp, cmd);
/* Turn off the LED. */ /* Turn off the LED. */
@ -789,7 +789,7 @@ sdhc_start_command(struct sdhc_host *hp, struct sdmmc_command *cmd)
* Start a CPU data transfer. Writing to the high order byte * Start a CPU data transfer. Writing to the high order byte
* of the SDHC_COMMAND register triggers the SD command. (1.5) * of the SDHC_COMMAND register triggers the SD command. (1.5)
*/ */
HWRITE2(hp, SDHC_BLOCK_SIZE, blksize); HWRITE2(hp, SDHC_BLOCK_SIZE, blksize | 7<<12);
if (blkcount > 0) if (blkcount > 0)
HWRITE2(hp, SDHC_BLOCK_COUNT, blkcount); HWRITE2(hp, SDHC_BLOCK_COUNT, blkcount);
HWRITE4(hp, SDHC_ARGUMENT, cmd->c_arg); HWRITE4(hp, SDHC_ARGUMENT, cmd->c_arg);
@ -804,8 +804,7 @@ sdhc_start_command(struct sdhc_host *hp, struct sdmmc_command *cmd)
void void
sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd) sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
{ {
u_char *datap = cmd->c_data; int datalen;
int i, datalen;
int mask; int mask;
int error; int error;
int status; int status;
@ -815,7 +814,7 @@ sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
SDHC_BUFFER_READ_ENABLE : SDHC_BUFFER_WRITE_ENABLE; SDHC_BUFFER_READ_ENABLE : SDHC_BUFFER_WRITE_ENABLE;
error = 0; error = 0;
datalen = cmd->c_datalen; datalen = cmd->c_datalen;
blkcnt = (cmd->c_datalen / 512); blkcnt = (datalen / 512);
DPRINTF(1,("%s: resp=%#x datalen=%d\n", HDEVNAME(hp), DPRINTF(1,("%s: resp=%#x datalen=%d\n", HDEVNAME(hp),
MMC_R1(cmd->c_resp), datalen)); MMC_R1(cmd->c_resp), datalen));
@ -833,13 +832,13 @@ sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
left = HREAD2(hp, SDHC_BLOCK_COUNT); left = HREAD2(hp, SDHC_BLOCK_COUNT);
DPRINTF(2,("%s: dma left:%#x\n", HDEVNAME(hp), DPRINTF(2,("%s: dma left:%#x\n", HDEVNAME(hp),
left)); left));
cmd->c_buf = cmd->c_data + (blkcnt - left)*512; // FIXME: why do we need -0x200 here?
cmd->c_buf = cmd->c_data + cmd->c_datalen - left*512 - 0x200;
HWRITE4(hp, SDHC_DMA_ADDR, HWRITE4(hp, SDHC_DMA_ADDR,
dma_addr(cmd->c_buf)); dma_addr(cmd->c_buf));
continue; continue;
} }
if (ISSET(status, SDHC_TRANSFER_COMPLETE)) { if (ISSET(status, SDHC_TRANSFER_COMPLETE)) {
gecko_printf("transfer complete!\n");
break; break;
} }
} }
@ -975,12 +974,12 @@ sdhc_wait_intr(struct sdhc_host *hp, int mask, int timo)
status = hp->intr_status & mask; status = hp->intr_status & mask;
for (timo = 1000; timo > 0; timo--) { for (timo = 500; timo > 0; timo--) {
if (hp->intr_status != 0) { if (hp->intr_status != 0) {
status = hp->intr_status & mask; status = hp->intr_status & mask;
break; break;
} }
sdmmc_delay(10); sdmmc_delay(1000);
} }
if (timo == 0) { if (timo == 0) {
status |= SDHC_ERROR_INTERRUPT; status |= SDHC_ERROR_INTERRUPT;
@ -1063,7 +1062,7 @@ sdhc_intr(void *arg)
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.device = IPC_DEV_SDHC; req.device = IPC_DEV_SDHC;
req.req = IPC_SDHC_DISCOVER; req.req = IPC_SDHC_DISCOVER;
req.args[0] = hp->sdmmc; req.args[0] = (u32)hp->sdmmc;
ipc_add_slow(&req); ipc_add_slow(&req);
} }
@ -1073,7 +1072,7 @@ sdhc_intr(void *arg)
*/ */
if (ISSET(status, SDHC_BUFFER_READ_READY| if (ISSET(status, SDHC_BUFFER_READ_READY|
SDHC_BUFFER_WRITE_READY|SDHC_COMMAND_COMPLETE| SDHC_BUFFER_WRITE_READY|SDHC_COMMAND_COMPLETE|
SDHC_TRANSFER_COMPLETE)) { SDHC_TRANSFER_COMPLETE|SDHC_DMA_INTERRUPT)) {
hp->intr_status |= status; hp->intr_status |= status;
wakeup(&hp->intr_status); wakeup(&hp->intr_status);
} }

18
sdmmc.c
View File

@ -358,8 +358,6 @@ int sdmmc_read(struct device *dev, u32 blk_start, u32 blk_count, void *data)
struct sdmmc_card *c = &cards[no]; struct sdmmc_card *c = &cards[no];
struct sdmmc_command cmd; struct sdmmc_command cmd;
gecko_printf("reading %d bytes to %p\n", blk_count*512,data);
if (c->inserted == 0) { if (c->inserted == 0) {
gecko_printf("sdmmc: READ: no card inserted.\n"); gecko_printf("sdmmc: READ: no card inserted.\n");
return -1; return -1;
@ -379,10 +377,7 @@ int sdmmc_read(struct device *dev, u32 blk_start, u32 blk_count, void *data)
DPRINTF(2, ("sdmmc: MMC_READ_BLOCK_MULTIPLE\n")); DPRINTF(2, ("sdmmc: MMC_READ_BLOCK_MULTIPLE\n"));
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
if (blk_count == 1) cmd.c_opcode = MMC_READ_BLOCK_MULTIPLE;
cmd.c_opcode = MMC_READ_BLOCK_MULTIPLE;
else
cmd.c_opcode = MMC_READ_BLOCK_MULTIPLE;
if (c->sdhc_blockmode) if (c->sdhc_blockmode)
cmd.c_arg = blk_start; cmd.c_arg = blk_start;
else else
@ -393,8 +388,6 @@ int sdmmc_read(struct device *dev, u32 blk_start, u32 blk_count, void *data)
cmd.c_flags = SCF_RSP_R1 | SCF_CMD_READ; cmd.c_flags = SCF_RSP_R1 | SCF_CMD_READ;
sdmmc_host_exec_command(c, &cmd); sdmmc_host_exec_command(c, &cmd);
gecko_printf("arg: %08x %08x\n", cmd.c_arg, blk_start);
if (cmd.c_error) { if (cmd.c_error) {
gecko_printf("sdmmc: MMC_READ_BLOCK_MULTIPLE failed for " gecko_printf("sdmmc: MMC_READ_BLOCK_MULTIPLE failed for "
"card %d with %d", no, cmd.c_error); "card %d with %d", no, cmd.c_error);
@ -430,10 +423,7 @@ int sdmmc_write(struct device *dev, u32 blk_start, u32 blk_count, void *data)
DPRINTF(2, ("sdmmc: MMC_WRITE_BLOCK_MULTIPLE\n")); DPRINTF(2, ("sdmmc: MMC_WRITE_BLOCK_MULTIPLE\n"));
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
if (blk_count == 1) cmd.c_opcode = MMC_WRITE_BLOCK_MULTIPLE;
cmd.c_opcode = MMC_WRITE_BLOCK_SINGLE;
else
cmd.c_opcode = MMC_WRITE_BLOCK_MULTIPLE;
if (c->sdhc_blockmode) if (c->sdhc_blockmode)
cmd.c_arg = blk_start; cmd.c_arg = blk_start;
else else
@ -467,14 +457,14 @@ void sdmmc_ipc(volatile ipc_request *req)
req->args[1], (void *)req->args[2]); req->args[1], (void *)req->args[2]);
dc_flushrange((void *)req->args[2], dc_flushrange((void *)req->args[2],
req->args[1]*SDMMC_DEFAULT_BLOCKLEN); req->args[1]*SDMMC_DEFAULT_BLOCKLEN);
ipc_post(req->code, req->tag, 1); ipc_post(req->code, req->tag, 1, ret);
break; break;
case IPC_SDMMC_WRITE: case IPC_SDMMC_WRITE:
dc_invalidaterange((void *)req->args[2], dc_invalidaterange((void *)req->args[2],
req->args[1]*SDMMC_DEFAULT_BLOCKLEN); req->args[1]*SDMMC_DEFAULT_BLOCKLEN);
ret = sdmmc_write(SDMMC_DEFAULT_DEVICE, req->args[0], ret = sdmmc_write(SDMMC_DEFAULT_DEVICE, req->args[0],
req->args[1], (void *)req->args[2]); req->args[1], (void *)req->args[2]);
ipc_post(req->code, req->tag, 1); ipc_post(req->code, req->tag, 1, ret);
break; break;
} }
} }