PERFORCE change 106426 for review
Warner Losh
imp at FreeBSD.org
Wed Sep 20 16:27:29 PDT 2006
http://perforce.freebsd.org/chv.cgi?CH=106426
Change 106426 by imp at imp_lighthouse on 2006/09/20 23:27:19
checkpoint
Affected files ...
.. //depot/projects/arm/src/sys/arm/at91/at91_qdmmc.c#11 edit
.. //depot/projects/arm/src/sys/boot/arm/at91/libat91/mci_device.c#16 edit
.. //depot/projects/arm/src/sys/boot/arm/at91/libat91/sd-card.c#10 edit
Differences ...
==== //depot/projects/arm/src/sys/arm/at91/at91_qdmmc.c#11 (text+ko) ====
@@ -135,7 +135,8 @@
WR4(sc, MCI_CMDR, cmd);
// wait until completed
- while (!(RD4(sc, MCI_SR) & MCI_SR_CMDRDY));
+ while (!(RD4(sc, MCI_SR) & MCI_SR_CMDRDY))
+ continue;
error = RD4(sc, MCI_SR) & MCI_SR_ERROR;
if (error) {
@@ -712,13 +713,28 @@
#endif
}
-static void at91_qdmmc_task(void *arg) {
+static void
+at91_qdmmc_wait_ready(struct at91_qdmmc_softc *sc)
+{
+ int timeout = 100000;
+
+ // Why doesn't this bit ever clear? It does in the boot loader.
+ printf("Waiting status %#x\n", RD4(sc, MCI_SR));
+ while (!(RD4(sc, MCI_SR) & MCI_SR_NOTBUSY) && --timeout)
+ continue;
+ printf("Waited status %#x\n", RD4(sc, MCI_SR));
+}
+
+static void
+at91_qdmmc_task(void *arg)
+{
struct at91_qdmmc_softc *sc = (struct at91_qdmmc_softc*)arg;
struct bio *bp;
int status;
bus_addr_t addr;
int map = 0;
uint32_t *tmpbuf;
+ int sz;
tmpbuf = malloc(sc->cards[0].sector_size, M_DEVBUF, M_WAITOK);
AT91_QDMMC_LOCK(sc);
@@ -732,22 +748,16 @@
bioq_remove(&sc->cards[0].bio_queue, bp);
printf("at91_qdmmc_task: request %p\n", bp);
if (bp->bio_cmd == BIO_READ) {
- status = at91_qdmmc_SendCommand(sc->dev,
- SEL_DESEL_CARD_CMD, sc->cards[0].addr << 16);
- printf("at91_qdmmc_task: select_card-status(%x) = 0x%x\n", sc->cards[0].addr, status);
- status = at91_qdmmc_SendCommand(sc->dev,
- SET_BLOCKLEN_CMD, sc->cards[0].sector_size);
- printf("at91_qdmmc_task: set_blocklen-status = 0x%x\n", status);
printf("at91_qdmmc_task: read block %lld, bcount %ld\n", bp->bio_pblkno, bp->bio_bcount);
uint32_t block;
// Init Mode Register
- WR4(sc, MCI_MR, sc->cards[0].mode | (sc->cards[0].sector_size << 16));
+ WR4(sc, MCI_MR, sc->cards[0].mode | MCI_MR_PDCMODE |
+ (sc->cards[0].sector_size << 16));
printf("mode 0x%x\n", RD4(sc, MCI_MR));
- for (block = bp->bio_pblkno; block < bp->bio_pblkno + (bp->bio_bcount / sc->cards[0].sector_size); block++) {
+ sz = sc->cards[0].sector_size;
+ for (block = bp->bio_pblkno; block < bp->bio_pblkno + (bp->bio_bcount / sz); block++) {
- WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
-
- char *paddr = bp->bio_data + (block - bp->bio_pblkno) * sc->cards[0].sector_size;
+ char *paddr = bp->bio_data + (block - bp->bio_pblkno) * sz;
if (bus_dmamap_load(sc->dmatag, sc->map, paddr,
sc->cards[0].sector_size, at91_getaddr, &addr, 0) != 0)
@@ -755,23 +765,30 @@
map = 1;
bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_PREREAD);
+ at91_qdmmc_wait_ready(sc);
+ WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS);
WR4(sc, PDC_RPR, addr);
- WR4(sc, PDC_RCR, sc->cards[0].sector_size / 4);
- WR4(sc, PDC_PTCR, PDC_PTCR_RXTEN);
- WR4(sc, MCI_IER, MCI_SR_RXBUFF | MCI_SR_ENDRX);
+ WR4(sc, PDC_RCR, sz / 4);
- printf("status = 0x%x, paddr = %p, RPR = 0x%x, RCR = 0x%x\n", status, paddr,
+ printf("block = %#x paddr = %p, RPR = 0x%x, RCR = 0x%x\n", block, paddr,
RD4(sc, PDC_RPR), RD4(sc, PDC_RCR));
status = at91_qdmmc_SendCommand(sc->dev,
- READ_SINGLE_BLOCK_CMD, block * sc->cards[0].sector_size);
+ READ_SINGLE_BLOCK_CMD, block * sz);
+ WR4(sc, MCI_IER, MCI_SR_RXBUFF | MCI_SR_ENDRX);
+ WR4(sc, PDC_PTCR, PDC_PTCR_RXTEN);
+
printf("at91_qdmmc_task: read-status = 0x%x\n", status);
// wait for completion
printf("TO SLEEP, PURCHANCE TO DREAM\n");
+#if 0
msleep(sc, &sc->sc_mtx, PRIBIO, "endrx", 0);
printf("DONE SLEEPING\n");
+#endif
+ at91_qdmmc_wait_ready(sc);
+
// safety check
- while ((RD4(sc, MCI_SR) & MCI_SR_ENDRX) == 0)
+ while ((RD4(sc, MCI_SR) & MCI_SR_RXBUFF) == 0)
DELAY(700);
printf("DONE WAITING\n");
@@ -779,6 +796,7 @@
bus_dmamap_unload(sc->dmatag, sc->map);
map = 0;
+ WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS);
/* Fix Byteorder (Atmel Errata) */
uint32_t* base = (uint32_t*)paddr;
for (int i = 0; i < sc->cards[0].sector_size / 4; i++) {
==== //depot/projects/arm/src/sys/boot/arm/at91/libat91/mci_device.c#16 (text+ko) ====
@@ -166,53 +166,13 @@
unsigned sectorLength = 1 << log2sl;
///////////////////////////////////////////////////////////////////////
- if (pMCI_Device->pMCI_DeviceDesc->state != AT91C_MCI_IDLE) {
-#if IMP_DEBUG
- printf("1 state is 0x%x\n", pMCI_Device->pMCI_DeviceDesc->state);
-#endif
- return AT91C_READ_ERROR;
- }
-
+ if (pMCI_Device->pMCI_DeviceDesc->state != AT91C_MCI_IDLE)
+ return AT91C_READ_ERROR;
if ((AT91F_MCI_GetStatus(
- pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address) & AT91C_SR_READY_FOR_DATA) == 0) {
-#if IMP_DEBUG
- printf("2\n");
-#endif
- return AT91C_READ_ERROR;
- }
-
- if ( (src + sizeToRead) > pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity ) {
-#if IMP_DEBUG
- printf("3\n");
-#endif
- return AT91C_READ_ERROR;
- }
+ pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address) & AT91C_SR_READY_FOR_DATA) == 0)
+ return AT91C_READ_ERROR;
- // If source does not fit a begin of a block
- if ((src & (sectorLength - 1)) != 0) {
-#if IMP_DEBUG
- printf("4\n");
-#endif
- return AT91C_READ_ERROR;
- }
-
- // Test if the MMC supports Partial Read Block
- // ALWAYS SUPPORTED IN SD Memory Card
- if( (sizeToRead < sectorLength)
- && (pMCI_Device->pMCI_DeviceFeatures->Read_Partial == 0x00) ) {
-#if IMP_DEBUG
- printf("5\n");
-#endif
- return AT91C_READ_ERROR;
- }
-
- if( sizeToRead > sectorLength) {
-#if IMP_DEBUG
- printf("6\n");
-#endif
- return AT91C_READ_ERROR;
- }
///////////////////////////////////////////////////////////////////////
// Init Mode Register
@@ -308,7 +268,7 @@
AT91S_MCIDeviceStatus
AT91F_MCI_MMC_SelectCard(AT91PS_MciDevice pMCI_Device, unsigned int relative_card_address)
{
- int status;
+ int status;
//* Check if the MMC card chosen is already the selected one
status = AT91F_MCI_GetStatus(relative_card_address);
@@ -319,19 +279,20 @@
if ((status & AT91C_SR_CARD_SELECTED) == AT91C_SR_CARD_SELECTED)
return AT91C_CARD_SELECTED_OK;
- //* Search for the MMC Card to be selected, status = the Corresponding Device Number
+ //* Search for the MMC Card to be selected,
+ // status = the Corresponding Device Number
status = 0;
while( (pMCI_Device->pMCI_DeviceFeatures[status].Relative_Card_Address != relative_card_address)
&& (status < AT91C_MAX_MCI_CARDS) )
status++;
if (status > AT91C_MAX_MCI_CARDS)
- return AT91C_CARD_SELECTED_ERROR;
+ return AT91C_CARD_SELECTED_ERROR;
- if (AT91F_MCI_SendCommand(SEL_DESEL_CARD_CMD,
- pMCI_Device->pMCI_DeviceFeatures[status].Relative_Card_Address << 16) == AT91C_CMD_SEND_OK)
- return AT91C_CARD_SELECTED_OK;
- return AT91C_CARD_SELECTED_ERROR;
+ if (AT91F_MCI_SendCommand(SEL_DESEL_CARD_CMD,
+ pMCI_Device->pMCI_DeviceFeatures[status].Relative_Card_Address << 16) == AT91C_CMD_SEND_OK)
+ return AT91C_CARD_SELECTED_OK;
+ return AT91C_CARD_SELECTED_ERROR;
}
#endif
==== //depot/projects/arm/src/sys/boot/arm/at91/libat91/sd-card.c#10 (text+ko) ====
@@ -47,8 +47,6 @@
#include "lib.h"
#include "sd-card.h"
-//#define IMP_DEBUG 1
-
#define AT91C_MCI_TIMEOUT 1000000 /* For AT91F_MCIDeviceWaitReady */
#define BUFFER_SIZE_MCI_DEVICE 512
#define MASTER_CLOCK 60000000
@@ -85,11 +83,6 @@
}
while( !(status & AT91C_MCI_NOTBUSY) && (timeout>0) );
-#if IMP_DEBUG
- if (timeout == 0)
- printf("Timeout, status is 0x%x\n", status);
-#endif
-
//TODO: Make interrupts work!
AT91F_MCI_Handler();
}
@@ -103,10 +96,6 @@
AT91S_MCIDeviceStatus status;
int sizeToWrite;
-#if IMP_DEBUG
- printf("\n");
-#endif
-
//See if we are requested to write partial sectors, and have the capability to do so
if ((length % sectorLength) && !(MCI_Device_Features.Write_Partial))
//Return error if appropriat
@@ -173,85 +162,26 @@
{
unsigned log2sl = MCI_Device.pMCI_DeviceFeatures->READ_BL_LEN;
unsigned sectorLength = 1 << log2sl;
- unsigned slmask = sectorLength - 1;
-// unsigned sector = (unsigned)source >> log2sl;
- unsigned offset = (unsigned)source & slmask;
AT91S_MCIDeviceStatus status;
int sizeToRead;
unsigned int *walker;
-#if IMP_DEBUG
- printf("Reading 0x%x bytes into ARM Addr 0x%x from card offset 0x%x\n",
- length, dest, source);
-#endif
-
-
- //See if we are requested to read partial sectors, and have the capability to do so
- if ((length & slmask) && !(MCI_Device_Features.Read_Partial))
- //Return error if appropriat
- return MCI_UNSUPP_SIZE_ERROR;
-
- //See if we are requested to read from anywhere but a sectors' boundary
- //and have the capability to do so
- if ((offset) && !(MCI_Device_Features.Read_Partial))
- //Return error if appropriat
- return MCI_UNSUPP_OFFSET_ERROR;
-
- //If the address we're trying to read != sector boundary
- if (offset) {
- //* Wait MCI Device Ready
- AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
-
- //Calculate the nr of bytes to read
- sizeToRead = sectorLength - offset;
- //Do the writing
- status = AT91F_MCI_ReadBlock(&MCI_Device, source, (unsigned int*)dest, sizeToRead);
- //TODO:Status checking
- if (status != AT91C_READ_OK) {
-#if IMP_DEBUG
- printf("STATUS is 0x%x\n", status);
-#endif
- return -1;
- }
-
- //* Wait MCI Device Ready
- AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
- // Fix erratum in MCI part
- for (walker = (unsigned int *)dest;
- walker < (unsigned int *)(dest + sizeToRead); walker++)
- *walker = swap(*walker);
-
- //Update counters & pointers
- length -= sizeToRead;
- dest += sizeToRead;
- source += sizeToRead;
- }
-
//As long as there is data to read
while (length)
{
- //See if we've got at least a sector to read
if (length > sectorLength)
sizeToRead = sectorLength;
- //Else just write the remainder
else
sizeToRead = length;
AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
- //Do the writing
- status = AT91F_MCI_ReadBlock(&MCI_Device, source, (unsigned int*)dest, sizeToRead);
-#if IMP_DEBUG
- printf("Reading 0x%x Addr 0x%x card 0x%x\n",
- sizeToRead, dest, source);
-#endif
+ //Do the reading
+ status = AT91F_MCI_ReadBlock(&MCI_Device, source,
+ (unsigned int*)dest, sizeToRead);
//TODO:Status checking
- if (status != AT91C_READ_OK) {
-#if IMP_DEBUG
- printf("STATUS is 0x%x\n", status);
-#endif
+ if (status != AT91C_READ_OK)
return -1;
- }
//* Wait MCI Device Ready
AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
@@ -301,7 +231,7 @@
// status = ( AT91C_BASE_MCI->MCI_SR & AT91C_BASE_MCI->MCI_IMR );
status = AT91C_BASE_MCI->MCI_SR;
- AT91F_MCI_Device_Handler(&MCI_Device,status);
+ AT91F_MCI_Device_Handler(&MCI_Device, status);
}
//*----------------------------------------------------------------------------
More information about the p4-projects
mailing list