sdhc/sdmmc is getting closer to read valid data :>

This commit is contained in:
Sven Peter 2009-04-12 13:17:44 +02:00 committed by bushing
parent cccd6f5332
commit 2ad64f59a8
5 changed files with 148 additions and 26 deletions

View File

@ -7,6 +7,7 @@
#include "diskio.h" #include "diskio.h"
#include "string.h" #include "string.h"
#include "sdmmc.h"
//#include "sdhc.h" //#include "sdhc.h"
#ifndef MEM2_BSS #ifndef MEM2_BSS
@ -23,15 +24,11 @@ DSTATUS disk_initialize (
BYTE drv /* Physical drive nmuber (0..) */ BYTE drv /* Physical drive nmuber (0..) */
) )
{ {
s32 ret; if (sdmmc_check_card(SDMMC_DEFAULT_DEVICE) == SDMMC_NO_CARD)
// sd_init(&sdhci, 0);
// ret = sd_mount(&sdhci);
if (ret < 0)
return STA_NOINIT; return STA_NOINIT;
else
return disk_status(drv); sdmmc_ack_card(SDMMC_DEFAULT_DEVICE);
return disk_status(drv);
} }
@ -46,7 +43,10 @@ DSTATUS disk_status (
// if (sd_inserted(&sdhci) == 0) // if (sd_inserted(&sdhci) == 0)
// return STA_NODISK; // return STA_NODISK;
return 0; if (sdmmc_check_card(SDMMC_DEFAULT_DEVICE) == SDMMC_INSERTED)
return 0;
else
return STA_NODISK;
} }
@ -66,10 +66,10 @@ DRESULT disk_read (
res = RES_OK; res = RES_OK;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
/* if (sd_read(&sdhci, sector + i, 1, buffer) != 0) { if (sdmmc_read(SDMMC_DEFAULT_DEVICE, sector+i, 1, buffer) != 0){
res = RES_ERROR; res = RES_ERROR;
break; break;
}*/ }
memcpy(buff + i * 512, buffer, 512); memcpy(buff + i * 512, buffer, 512);
} }

View File

@ -5,7 +5,7 @@ EXTERN(__ipc_info)
ENTRY(_start) ENTRY(_start)
__stack_size = 0x800; __stack_size = 0x800;
__irqstack_size = 0x400; /* blame the bsd's sdhc_intr function */ __irqstack_size = 0x200; /* blame the bsd's sdhc_intr function */
__excstack_size = 0x100; __excstack_size = 0x100;
MEMORY { MEMORY {

24
sdhc.c
View File

@ -45,7 +45,7 @@
#include "utils.h" #include "utils.h"
#include "ipc.h" #include "ipc.h"
#define SDHC_DEBUG 0 #define SDHC_DEBUG 1
#define SDHC_COMMAND_TIMEOUT 0 #define SDHC_COMMAND_TIMEOUT 0
#define SDHC_BUFFER_TIMEOUT 0 #define SDHC_BUFFER_TIMEOUT 0
@ -159,7 +159,7 @@ void sdhc_read_data(struct sdhc_host *, u_char *, int);
void sdhc_write_data(struct sdhc_host *, u_char *, int); void sdhc_write_data(struct sdhc_host *, u_char *, int);
#ifdef SDHC_DEBUG #ifdef SDHC_DEBUG
int sdhcdebug = 0; int sdhcdebug = 2;
#define DPRINTF(n,s) do { if ((n) <= sdhcdebug) gecko_printf s; } while (0) #define DPRINTF(n,s) do { if ((n) <= sdhcdebug) gecko_printf s; } while (0)
void sdhc_dump_regs(struct sdhc_host *); void sdhc_dump_regs(struct sdhc_host *);
#else #else
@ -972,8 +972,8 @@ sdhc_intr(void *arg)
/* Acknowledge the interrupts we are about to handle. */ /* Acknowledge the interrupts we are about to handle. */
HWRITE2(hp, SDHC_NINTR_STATUS, status); HWRITE2(hp, SDHC_NINTR_STATUS, status);
DPRINTF(2,("%s: interrupt status=%d\n", HDEVNAME(hp), // DPRINTF(2,("%s: interrupt status=%d\n", HDEVNAME(hp),
status)); // status));
/* Claim this interrupt. */ /* Claim this interrupt. */
@ -988,11 +988,11 @@ sdhc_intr(void *arg)
/* Acknowledge error interrupts. */ /* Acknowledge error interrupts. */
error = HREAD2(hp, SDHC_EINTR_STATUS); error = HREAD2(hp, SDHC_EINTR_STATUS);
HWRITE2(hp, SDHC_EINTR_STATUS, error); HWRITE2(hp, SDHC_EINTR_STATUS, error);
DPRINTF(2,("%s: error interrupt, status=%d\n", // DPRINTF(2,("%s: error interrupt, status=%d\n",
HDEVNAME(hp), error)); // HDEVNAME(hp), error));
if (ISSET(error, SDHC_CMD_TIMEOUT_ERROR| if (ISSET(error, SDHC_CMD_TIMEOUT_ERROR|
SDHC_DATA_TIMEOUT_ERROR)) { SDHC_DATA_TIMEOUT_ERROR)) {
hp->intr_error_status |= error; hp->intr_error_status |= error;
hp->intr_status |= status; hp->intr_status |= status;
wakeup(&hp->intr_status); wakeup(&hp->intr_status);
@ -1004,7 +1004,7 @@ sdhc_intr(void *arg)
* TODO: move request to slow queue to make sure that * TODO: move request to slow queue to make sure that
* we're not blocking other IRQs * we're not blocking other IRQs
*/ */
if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) { if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) {
ipc_request req; ipc_request req;
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.device = IPC_DEV_SD; req.device = IPC_DEV_SD;
@ -1019,7 +1019,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)) {
hp->intr_status |= status; hp->intr_status |= status;
wakeup(&hp->intr_status); wakeup(&hp->intr_status);
} }
@ -1027,8 +1027,8 @@ sdhc_intr(void *arg)
/* /*
* Service SD card interrupts. * Service SD card interrupts.
*/ */
if (ISSET(status, SDHC_CARD_INTERRUPT)) { if (ISSET(status, SDHC_CARD_INTERRUPT)) {
DPRINTF(0,("%s: card interrupt\n", HDEVNAME(hp))); // DPRINTF(0,("%s: card interrupt\n", HDEVNAME(hp)));
HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT); HCLR2(hp, SDHC_NINTR_STATUS_EN, SDHC_CARD_INTERRUPT);
// sdmmc_card_intr(hp->sdmmc); // sdmmc_card_intr(hp->sdmmc);
} }
@ -1064,7 +1064,7 @@ sdhc_dump_regs(struct sdhc_host *hp)
#endif #endif
#include "hollywood.h" #include "hollywood.h"
static struct sdhc_softc __softc; static struct sdhc_softc __softc MEM2_BSS;
void sdhc_irq(void) void sdhc_irq(void)
{ {

111
sdmmc.c
View File

@ -47,12 +47,14 @@ struct sdmmc_card {
int no; int no;
int inserted; int inserted;
int sdhc_blockmode; int sdhc_blockmode;
int selected;
int new_card; // set to 1 everytime a new card is inserted
u32 cid; u32 cid;
u16 rca; u16 rca;
}; };
static struct sdmmc_card cards[SDHC_MAX_HOSTS]; static struct sdmmc_card cards[SDHC_MAX_HOSTS] MEM2_BSS;
static int n_cards = 0; static int n_cards = 0;
static inline int sdmmc_host_reset(struct sdmmc_card *card) static inline int sdmmc_host_reset(struct sdmmc_card *card)
@ -129,6 +131,7 @@ void sdmmc_needs_discover(struct device *dev)
DPRINTF(0, ("sdmmc: card %d needs discovery.\n", no)); DPRINTF(0, ("sdmmc: card %d needs discovery.\n", no));
sdmmc_host_reset(c); sdmmc_host_reset(c);
c->new_card = 1;
if (!sdmmc_host_card_detect(c)) { if (!sdmmc_host_card_detect(c)) {
DPRINTF(1, ("sdmmc: card %d (no longer?) inserted.\n", no)); DPRINTF(1, ("sdmmc: card %d (no longer?) inserted.\n", no));
@ -209,6 +212,11 @@ void sdmmc_needs_discover(struct device *dev)
goto out_power; goto out_power;
} }
if (ISSET(MMC_R1(cmd.c_resp), SD_OCR_SDHC_CAP))
c->sdhc_blockmode = 1;
else
c->sdhc_blockmode = 0;
DPRINTF(2, ("sdmmc: MMC_ALL_SEND_CID\n")); DPRINTF(2, ("sdmmc: MMC_ALL_SEND_CID\n"));
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
cmd.c_opcode = MMC_ALL_SEND_CID; cmd.c_opcode = MMC_ALL_SEND_CID;
@ -237,7 +245,23 @@ void sdmmc_needs_discover(struct device *dev)
c->rca = MMC_R1(cmd.c_resp)>>16; c->rca = MMC_R1(cmd.c_resp)>>16;
DPRINTF(2, ("sdmmc: rca: %08x\n", c->rca)); DPRINTF(2, ("sdmmc: rca: %08x\n", c->rca));
c->selected = 0;
c->inserted = 1; c->inserted = 1;
sdmmc_select(dev);
DPRINTF(2, ("sdmmc: MMC_SET_BLOCKLEN\n"));
memset(&cmd, 0, sizeof(cmd));
cmd.c_opcode = MMC_SET_BLOCKLEN;
cmd.c_arg = SDMMC_DEFAULT_BLOCKLEN;
cmd.c_flags = SCF_RSP_R1;
sdmmc_host_exec_command(c, &cmd);
if (cmd.c_error) {
gecko_printf("sdmmc: MMC_SET_BLOCKLEN failed with %d for card %d\n",
cmd.c_error, no);
c->inserted = c->selected = 0;
goto out_clock;
}
return; return;
out_clock: out_clock:
@ -286,3 +310,88 @@ out:
#endif #endif
} }
int sdmmc_select(struct device *dev)
{
int no = (int)dev;
struct sdmmc_card *c = &cards[no];
struct sdmmc_command cmd;
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;
sdmmc_host_exec_command(c, &cmd);
if (cmd.c_error) {
gecko_printf("sdmmc: MMC_SELECT card failed with %d for %d.\n",
cmd.c_error, no);
return -1;
}
c->selected = 1;
return 0;
}
int sdmmc_check_card(struct device *dev)
{
int no = (int)dev;
struct sdmmc_card *c = &cards[no];
if (c->inserted == 0)
return SDMMC_NO_CARD;
if (c->new_card == 1)
return SDMMC_NEW_CARD;
return SDMMC_INSERTED;
}
void sdmmc_ack_card(struct device *dev)
{
int no = (int)dev;
struct sdmmc_card *c = &cards[no];
c->new_card = 0;
}
int sdmmc_read(struct device *dev, u32 blk_start, u32 blk_count, void *data)
{
int no = (int)dev;
struct sdmmc_card *c = &cards[no];
struct sdmmc_command cmd;
if (c->inserted == 0) {
gecko_printf("sdmmc: READ: no card inserted.\n");
return -1;
}
if (c->selected == 0) {
if (sdmmc_select(dev) < 0) {
gecko_printf("sdmmc: READ: cannot select card.\n");
return -1;
}
}
if (c->new_card == 1) {
gecko_printf("sdmmc: new card inserted but not acknowledged yet.\n");
return -1;
}
DPRINTF(2, ("sdmmc: MMC_READ_BLOCK_MULTIPLE\n"));
memset(&cmd, 0, sizeof(cmd));
cmd.c_opcode = MMC_READ_BLOCK_MULTIPLE;
if (c->sdhc_blockmode)
cmd.c_arg = blk_start;
else
cmd.c_arg = blk_start * SDMMC_DEFAULT_BLOCKLEN;
cmd.c_data = data;
cmd.c_datalen = blk_count * SDMMC_DEFAULT_BLOCKLEN;
cmd.c_blklen = SDMMC_DEFAULT_BLOCKLEN;
cmd.c_flags = SCF_RSP_R1 | SCF_CMD_READ;
sdmmc_host_exec_command(c, &cmd);
if (cmd.c_error) {
gecko_printf("sdmmc: MMC_READ_BLOCK_MULTIPLE failed for "
"card %d with %d", no, cmd.c_error);
return -1;
}
gecko_printf("success!!\n");
return 0;
}

15
sdmmc.h
View File

@ -22,12 +22,25 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#ifndef __SDMMC_H__ #ifndef __SDMMC_H__
#define __SDMMC_H__ 1 #define __SDMMC_H__ 1
#include "sdmmcvar.h" #include "bsdtypes.h"
#include "sdmmcchip.h" #include "sdmmcchip.h"
#include "sdmmcvar.h"
#define SDMMC_DEFAULT_CLOCK 25000 #define SDMMC_DEFAULT_CLOCK 25000
#define SDMMC_DEFAULT_BLOCKLEN 512
#define SDMMC_NO_CARD 1
#define SDMMC_NEW_CARD 2
#define SDMMC_INSERTED 3
// HACK
#define SDMMC_DEFAULT_DEVICE ((struct device *)0)
struct device *sdmmc_attach(struct sdmmc_chip_functions *functions, struct device *sdmmc_attach(struct sdmmc_chip_functions *functions,
sdmmc_chipset_handle_t handle, const char *name, int no); sdmmc_chipset_handle_t handle, const char *name, int no);
void sdmmc_needs_discover(struct device *dev); void sdmmc_needs_discover(struct device *dev);
int sdmmc_select(struct device *dev);
int sdmmc_check_card(struct device *dev);
void sdmmc_ack_card(struct device *dev);
int sdmmc_read(struct device *dev, u32 blk_start, u32 blk_count, void *data);
#endif #endif