mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-16 16:39:25 +01:00
fixes from booto for CMD16 problem
This commit is contained in:
parent
45990d9cfc
commit
e000264f3b
46
sdhc.c
46
sdhc.c
@ -47,6 +47,7 @@
|
||||
|
||||
#define HDEVNAME(hp) ((hp)->sc->sc_dev.dv_xname)
|
||||
#define sdmmc_delay(t) udelay(t)
|
||||
#define sdhc_wait_intr(a,b,c) sdhc_wait_intr_debug(__func__, __LINE__, a, b, c)
|
||||
|
||||
static inline u32 bus_space_read_4(bus_space_handle_t ioh, u32 reg)
|
||||
{
|
||||
@ -136,11 +137,12 @@ void sdhc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *);
|
||||
int sdhc_start_command(struct sdhc_host *, struct sdmmc_command *);
|
||||
int sdhc_wait_state(struct sdhc_host *, u_int32_t, u_int32_t);
|
||||
int sdhc_soft_reset(struct sdhc_host *, int);
|
||||
int sdhc_wait_intr(struct sdhc_host *, int, int);
|
||||
void sdhc_reset_intr_status(struct sdhc_host *hp);
|
||||
int sdhc_wait_intr_debug(const char *func, int line, struct sdhc_host *, int, int);
|
||||
void sdhc_transfer_data(struct sdhc_host *, struct sdmmc_command *);
|
||||
void sdhc_read_data(struct sdhc_host *, u_char *, int);
|
||||
void sdhc_write_data(struct sdhc_host *, u_char *, int);
|
||||
|
||||
#define SDHC_DEBUG 1
|
||||
#ifdef SDHC_DEBUG
|
||||
int sdhcdebug = 2;
|
||||
#define DPRINTF(n,s) do { if ((n) <= sdhcdebug) gecko_printf s; } while (0)
|
||||
@ -508,6 +510,7 @@ sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq)
|
||||
int timo;
|
||||
int error = 0;
|
||||
|
||||
gecko_printf("%s(%d)\n", __FUNCTION__, freq);
|
||||
#ifdef DIAGNOSTIC
|
||||
/* Must not stop the clock if commands are in progress. */
|
||||
if (ISSET(HREAD4(hp, SDHC_PRESENT_STATE), SDHC_CMD_INHIBIT_MASK) &&
|
||||
@ -610,6 +613,9 @@ sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
|
||||
cmd->c_timeout = SDHC_COMMAND_TIMEOUT;
|
||||
}
|
||||
|
||||
|
||||
sdhc_reset_intr_status(hp);
|
||||
|
||||
/*
|
||||
* Start the MMC command, or mark `cmd' as failed and return.
|
||||
*/
|
||||
@ -625,14 +631,19 @@ sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
|
||||
* Wait until the command phase is done, or until the command
|
||||
* is marked done for any other reason.
|
||||
*/
|
||||
if (!sdhc_wait_intr(hp, SDHC_COMMAND_COMPLETE,
|
||||
cmd->c_timeout)) {
|
||||
|
||||
int status = sdhc_wait_intr(hp, SDHC_COMMAND_COMPLETE, cmd->c_timeout);
|
||||
if (!ISSET(status, SDHC_COMMAND_COMPLETE)) {
|
||||
cmd->c_error = ETIMEDOUT;
|
||||
gecko_printf("timeout dump: error_intr: 0x%x intr: 0x%x\n", hp->intr_error_status, hp->intr_status);
|
||||
sdhc_dump_regs(hp);
|
||||
SET(cmd->c_flags, SCF_ITSDONE);
|
||||
hp->data_command = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
gecko_printf("command_complete, continuing...\n");
|
||||
|
||||
/*
|
||||
* The host controller removes bits [0:7] from the response
|
||||
* data (CRC) and we pass the data up unchanged to the bus
|
||||
@ -659,8 +670,8 @@ sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
|
||||
/* Turn off the LED. */
|
||||
HCLR1(hp, SDHC_HOST_CTL, SDHC_LED_ON);
|
||||
|
||||
DPRINTF(1,("%s: cmd %u done (flags=%#x error=%d)\n",
|
||||
HDEVNAME(hp), cmd->c_opcode, cmd->c_flags, cmd->c_error));
|
||||
DPRINTF(1,("%s: cmd %u done (flags=%#x error=%d prev state=%d)\n",
|
||||
HDEVNAME(hp), cmd->c_opcode, cmd->c_flags, cmd->c_error, (cmd->c_resp[0] >> 9) & 15));
|
||||
SET(cmd->c_flags, SCF_ITSDONE);
|
||||
hp->data_command = 0;
|
||||
}
|
||||
@ -797,6 +808,10 @@ sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ISSET(status, SDHC_TRANSFER_COMPLETE)) {
|
||||
gecko_printf("got a TRANSFER_COMPLETE: %08x\n", status);
|
||||
break;
|
||||
}
|
||||
if (ISSET(status, SDHC_DMA_INTERRUPT)) {
|
||||
DPRINTF(2,("%s: dma left:%#x\n", HDEVNAME(hp),
|
||||
HREAD2(hp, SDHC_BLOCK_COUNT)));
|
||||
@ -808,9 +823,6 @@ sdhc_transfer_data(struct sdhc_host *hp, struct sdmmc_command *cmd)
|
||||
HREAD4(hp, SDHC_DMA_ADDR));
|
||||
continue;
|
||||
}
|
||||
if (ISSET(status, SDHC_TRANSFER_COMPLETE)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
gecko_printf("fail.\n");
|
||||
@ -857,12 +869,17 @@ sdhc_soft_reset(struct sdhc_host *hp, int mask)
|
||||
HWRITE1(hp, SDHC_SOFTWARE_RESET, 0);
|
||||
return (ETIMEDOUT);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
void sdhc_reset_intr_status(struct sdhc_host *hp)
|
||||
{
|
||||
hp->intr_status = 0;
|
||||
}
|
||||
|
||||
int
|
||||
sdhc_wait_intr(struct sdhc_host *hp, int mask, int timo)
|
||||
sdhc_wait_intr_debug(const char *funcname, int line, struct sdhc_host *hp, int mask, int timo)
|
||||
{
|
||||
int status;
|
||||
|
||||
@ -887,11 +904,14 @@ sdhc_wait_intr(struct sdhc_host *hp, int mask, int timo)
|
||||
}
|
||||
hp->intr_status &= ~status;
|
||||
|
||||
DPRINTF(2,("%s: timo=%d intr status %#x error %#x\n", HDEVNAME(hp), timo, status,
|
||||
hp->intr_error_status));
|
||||
DPRINTF(2,("%s: funcname=%s, line=%d, timo=%d status=%#x intr status=%#x error %#x\n",
|
||||
HDEVNAME(hp), funcname, line, timo, status, hp->intr_status, hp->intr_error_status));
|
||||
|
||||
/* Command timeout has higher priority than command complete. */
|
||||
if (ISSET(status, SDHC_ERROR_INTERRUPT)) {
|
||||
gecko_printf("resetting due to error interrupt\n");
|
||||
sdhc_dump_regs(hp);
|
||||
|
||||
hp->intr_error_status = 0;
|
||||
(void)sdhc_soft_reset(hp, SDHC_RESET_DAT|SDHC_RESET_CMD);
|
||||
status = 0;
|
||||
|
9
sdmmc.c
9
sdmmc.c
@ -377,9 +377,13 @@ int sdmmc_select(struct device *dev)
|
||||
DPRINTF(2, ("sdmmc: MMC_SELECT_CARD\n"));
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.c_opcode = MMC_SELECT_CARD;
|
||||
cmd.c_arg = ((u32)c->rca)<<16;;
|
||||
cmd.c_flags = SCF_RSP_R1;
|
||||
cmd.c_arg = ((u32)c->rca)<<16;
|
||||
cmd.c_flags = SCF_RSP_R1B;
|
||||
sdmmc_host_exec_command(c, &cmd);
|
||||
gecko_printf("%s: resp=%x\n", __FUNCTION__, MMC_R1(cmd.c_resp));
|
||||
sdhc_dump_regs(c->handle);
|
||||
|
||||
// gecko_printf("present state = %x\n", HREAD4(hp, SDHC_PRESENT_STATE));
|
||||
if (cmd.c_error) {
|
||||
gecko_printf("sdmmc: MMC_SELECT card failed with %d for %d.\n",
|
||||
cmd.c_error, no);
|
||||
@ -423,6 +427,7 @@ int sdmmc_read(struct device *dev, u32 blk_start, u32 blk_count, void *data)
|
||||
struct sdmmc_card *c = &cards[no];
|
||||
struct sdmmc_command cmd;
|
||||
|
||||
gecko_printf("%s(%u, %u, %p)\n", __FUNCTION__, blk_start, blk_count, data);
|
||||
if (c->inserted == 0) {
|
||||
gecko_printf("sdmmc: READ: no card inserted.\n");
|
||||
return -1;
|
||||
|
Loading…
Reference in New Issue
Block a user