1
0
Fork 0
forked from len0rd/rockbox

rk27xx - tweak a bit sd driver and add some debuging code

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30447 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Marcin Bukat 2011-09-06 12:38:41 +00:00
parent 52c72fa185
commit 7d33d83218

View file

@ -49,6 +49,11 @@
#define RES_NO (-1) #define RES_NO (-1)
#define RK27XX_SD_DEBUG
/* debug stuff */
unsigned long sd_debug_time_rd = 0;
unsigned long sd_debug_time_wr = 0;
static tCardInfo card_info; static tCardInfo card_info;
/* for compatibility */ /* for compatibility */
@ -275,8 +280,6 @@ static int sd_init_card(void)
/* End of Card Identification Mode ************************************/ /* End of Card Identification Mode ************************************/
/* Card back to full speed 25MHz*/
SD_CTRL = (SD_CTRL & ~0x7FF) | 1; /* FIXME check this divider - OF uses 0 here*/
/* CMD9 send CSD */ /* CMD9 send CSD */
if(!send_cmd(SD_SEND_CSD, card_info.rca, RES_R2, card_info.csd)) if(!send_cmd(SD_SEND_CSD, card_info.rca, RES_R2, card_info.csd))
@ -290,6 +293,13 @@ static int sd_init_card(void)
if (!sd_wait_card_busy()) if (!sd_wait_card_busy())
return -21; return -21;
/* CMD6 */
if(!send_cmd(SD_SWITCH_FUNC, 0x80fffff1, RES_R1, &response))
return -8;
sleep(HZ/10);
/* Card back to full speed 25MHz*/
SD_CTRL = (SD_CTRL & ~0x7FF);
card_info.initialized = 1; card_info.initialized = 1;
return 0; return 0;
@ -399,6 +409,23 @@ static void init_controller(void)
MMU_CTRL = MMU_MMU0_BUFII | MMU_CPU_BUFI | MMU_BUFII_RESET | MMU_CTRL = MMU_MMU0_BUFII | MMU_CPU_BUFI | MMU_BUFII_RESET |
MMU_BUFII_BYTE | MMU_BUFI_RESET | MMU_BUFI_WORD; MMU_BUFII_BYTE | MMU_BUFI_RESET | MMU_BUFI_WORD;
/* setup A2A DMA CH0 for SD reads */
A2A_ISRC0 = (unsigned long)(&MMU_DATA);
A2A_ICNT0 = 512;
A2A_LCNT0 = 1;
/* setup A2A DMA CH1 for SD writes */
A2A_IDST1 = (unsigned long)(&MMU_DATA);
A2A_ICNT1 = 512;
A2A_LCNT1 = 1;
/* src and dst for CH0 and CH1 is AHB0 */
A2A_DOMAIN = 0;
#ifdef RK27XX_SD_DEBUG
/* setup Timer1 for profiling purposes */
TMR1CON = (1<<8)|(1<<3);
#endif
} }
int sd_init(void) int sd_init(void)
@ -424,6 +451,40 @@ int sd_init(void)
return 0; return 0;
} }
static inline void read_sd_data(unsigned char **dst)
{
commit_discard_dcache_range((const void *)*dst, 512);
A2A_IDST0 = (unsigned long)*dst;
A2A_CON0 = (3<<9) | /* burst 16 */
(1<<6) | /* fixed src */
(1<<3) | /* DMA start */
(2<<1) | /* word transfer size */
(1<<0); /* software mode */
/* wait for DMA engine to finish transfer */
while (A2A_DMA_STS & 1);
*dst += 512;
}
static inline void write_sd_data(unsigned char **src)
{
commit_discard_dcache_range((const void *)*src, 512);
A2A_ISRC1 = (unsigned long)*src;
A2A_CON1 = (3<<9) | /* burst 16 */
(1<<5) | /* fixed dst */
(1<<3) | /* DMA start */
(2<<1) | /* word transfer size */
(1<<0); /* software mode */
/* wait for DMA engine to finish transfer */
while (A2A_DMA_STS & 2);
*src += 512;
}
int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count, int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
void* buf) void* buf)
{ {
@ -444,12 +505,6 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
if(!(card_info.ocr & (1<<30))) if(!(card_info.ocr & (1<<30)))
start <<= 9; /* not SDHC */ start <<= 9; /* not SDHC */
/* setup A2A DMA CH0 */
A2A_ISRC0 = (unsigned long)(&MMU_DATA);
A2A_ICNT0 = 512;
A2A_LCNT0 = 1;
A2A_DOMAIN = 0;
while (retry_cnt++ < 20) while (retry_cnt++ < 20)
{ {
cnt = count; cnt = count;
@ -484,9 +539,17 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
while (cnt > 0) while (cnt > 0)
{ {
#ifdef RK27XX_SD_DEBUG
/* debug stuff */
TMR1LR = 0xffffffff;
#endif
/* wait for transfer completion */ /* wait for transfer completion */
semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK); semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
#ifdef RK27XX_DEBUG
/* debug stuff */
sd_debug_time_rd = 0xffffffff - TMR1CVR;
#endif
if (retry) if (retry)
{ {
/* data transfer error */ /* data transfer error */
@ -497,17 +560,6 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
/* exchange buffers */ /* exchange buffers */
mmu_switch_buff(); mmu_switch_buff();
A2A_IDST0 = (unsigned long)dst;
A2A_CON0 = (3<<9) | /* burst 16 */
(1<<6) | /* fixed src */
(1<<3) | /* DMA start */
(2<<1) | /* word transfer size */
(1<<0); /* software mode */
/* wait for DMA engine to finish transfer */
while (A2A_DMA_STS & 1);
dst += 512;
cnt--; cnt--;
if (cnt == 0) if (cnt == 0)
@ -515,6 +567,8 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
if (!send_cmd(SD_STOP_TRANSMISSION, 0, RES_R1b, &response)) if (!send_cmd(SD_STOP_TRANSMISSION, 0, RES_R1b, &response))
ret = -4; ret = -4;
read_sd_data(&dst);
break; break;
} }
else if (cnt == 1) else if (cnt == 1)
@ -523,6 +577,9 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
SD_DATAT = DATA_XFER_START | DATA_XFER_READ | SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
DATA_BUS_1LINE | DATA_XFER_DMA_DIS | DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
DATA_XFER_SINGLE; DATA_XFER_SINGLE;
read_sd_data(&dst);
} }
else else
{ {
@ -530,6 +587,8 @@ int sd_read_sectors(IF_MD2(int drive,) unsigned long start, int count,
SD_DATAT = DATA_XFER_START | DATA_XFER_READ | SD_DATAT = DATA_XFER_START | DATA_XFER_READ |
DATA_BUS_1LINE | DATA_XFER_DMA_DIS | DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
DATA_XFER_MULTI; DATA_XFER_MULTI;
read_sd_data(&dst);
} }
last_disk_activity = current_tick; last_disk_activity = current_tick;
@ -561,6 +620,12 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
(void) buf; (void) buf;
return -1; return -1;
#else #else
#ifdef RK27XX_SD_DEBUG
/* debug stuff */
TMR1LR = 0xffffffff;
#endif
unsigned long response; unsigned long response;
unsigned int retry_cnt = 0; unsigned int retry_cnt = 0;
int cnt, ret = 0; int cnt, ret = 0;
@ -576,12 +641,6 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
if(!(card_info.ocr & (1<<30))) if(!(card_info.ocr & (1<<30)))
start <<= 9; /* not SDHC */ start <<= 9; /* not SDHC */
/* setup A2A DMA CH0 */
A2A_IDST0 = (unsigned long)(&MMU_DATA);
A2A_ICNT0 = 512;
A2A_LCNT0 = 1;
A2A_DOMAIN = 0;
while (retry_cnt++ < 20) while (retry_cnt++ < 20)
{ {
cnt = count; cnt = count;
@ -591,17 +650,7 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
retry = false; /* reset retry flag */ retry = false; /* reset retry flag */
mmu_buff_reset(); /* reset recive buff state */ mmu_buff_reset(); /* reset recive buff state */
/* transfer data from receive buffer to the dest write_sd_data(&src); /* put data into transfer buffer */
* for (i=0; i<(512/4); i++)
* MMU_DATA = *src++;
*
* Below is DMA version in software mode.
*/
A2A_ISRC0 = (unsigned long)src;
A2A_CON0 = (3<<9) | (1<<5) | (1<<3) | (2<<1) | (1<<0);
while (A2A_DMA_STS & 1);
if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response)) if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response))
{ {
@ -629,20 +678,9 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
DATA_BUS_1LINE | DATA_XFER_DMA_DIS | DATA_BUS_1LINE | DATA_XFER_DMA_DIS |
DATA_XFER_MULTI; DATA_XFER_MULTI;
/* transfer data from receive buffer to the dest /* put more data */
* for (i=0; i<(512/4); i++) write_sd_data(&src);
* MMU_DATA = *src++;
*
* Below is DMA version in software mode.
*/
src += 512;
A2A_ISRC0 = (unsigned long)src;
A2A_CON0 = (3<<9) | (1<<5) | (1<<3) | (2<<1) | (1<<0);
while (A2A_DMA_STS & 1);
} }
/* wait for transfer completion */ /* wait for transfer completion */
semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK); semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
@ -670,6 +708,11 @@ int sd_write_sectors(IF_MD2(int drive,) unsigned long start, int count,
sd_enable(false); sd_enable(false);
mutex_unlock(&sd_mtx); mutex_unlock(&sd_mtx);
#ifdef RK27XX_SD_DEBUG
/* debug stuff */
sd_debug_time_wr = 0xffffffff - TMR1CVR;
#endif
return ret; return ret;
#endif /* defined(BOOTLOADER) */ #endif /* defined(BOOTLOADER) */