From owner-p4-projects@FreeBSD.ORG Wed Sep 20 23:27:29 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 62D6316A416; Wed, 20 Sep 2006 23:27:29 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3E8D016A407 for ; Wed, 20 Sep 2006 23:27:29 +0000 (UTC) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7720243D49 for ; Wed, 20 Sep 2006 23:27:28 +0000 (GMT) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k8KNRSXY099521 for ; Wed, 20 Sep 2006 23:27:28 GMT (envelope-from imp@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k8KNRSoi099518 for perforce@freebsd.org; Wed, 20 Sep 2006 23:27:28 GMT (envelope-from imp@freebsd.org) Date: Wed, 20 Sep 2006 23:27:28 GMT Message-Id: <200609202327.k8KNRSoi099518@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to imp@freebsd.org using -f From: Warner Losh To: Perforce Change Reviews Cc: Subject: PERFORCE change 106426 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 Sep 2006 23:27:29 -0000 http://perforce.freebsd.org/chv.cgi?CH=106426 Change 106426 by imp@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); } //*----------------------------------------------------------------------------