Date: Thu, 09 Jun 2005 10:52:08 +0300
From: Jukka Santala <donwulff_at_nic.fi>
To: kernel-discuss_at_handhelds.org
Subject: [Kernel-discuss] mmc_samsung.c fixes to MMC hangs/performance
I have written a couple of fixes for the s3c2410 MMC drivers. I only
have access to iPAQ h5550 and Transcend 45x 256MB SD card, however, so I
cannot test whether the fixes work with all combinations. If people with
different configurations could give it a spin hopefully we can get this
into the Handhelds kernel soon. It's written against
handhelds-pxa-2.4.19-rmk6-pxa1-hh37.6-r0 (Familiar 8.2) but should apply
against any reasonably recent Handhelds kernel.
There are three fixes in the patch:
1) On ARM architechture, pending IRQ flags must always be reset, or they
will keep being sent back for processing. The current driver doesn't
reset the pending IRQ when getting "ignoring mmc irq with null request"
error. This causes the device to frequently go into near endless loop
processing the same empty IRQ. Since interrupts are disabled during the
interrupt service routine, we can reset the interrupt flags at the
beginning.
2) Transcend 45x 256MB SD card specifies TAAC 0x8f, that translates to
80ms. The Samsung datasheets state "SDI data/busy timer register has
16-bit counter. In caise of 25MHz operation, the countable maximum is
2.6ms (40ns * 0x10000). But, some cards have very long access time
(TAAC), their TAAC are up to 100ms. In this case the SDI generates data
timeout error state." The timeout error is not currently handled,
causing the IO operation to hang. Unfortunately the chart provided in
the datasheet doesn't make much sense, but the concept is simple: If the
read access times out, temporarily reduce clock to 600kHz and try again.
This patch does just that, no matter how ugly it is.
3) Since the two fixes remove the two hangs I've had with the driver,
I've changed it to use the clock-speed specified by the card directly.
This works fine for me, but is the main thing that needs testing. If you
have problems with the patch, check out what /proc/bus/mmc/device says.
If it works, it should lead to small performance improvements even for
people who haven't experienced hangs before. Bit suspicious about why
the clock-speed is hardcoded, currently in two places, though.
There's still plenty of errors and warnings coming out of the MMC
driver, but at least with the above changes it works (for me) with good
performance and stability.
Patch attached, unless attachments are disabled.
-Donwulff
diff -r -u kernel.org/drivers/mmc/mmc_protocol.c kernel/drivers/mmc/mmc_protocol.c
--- kernel.org/drivers/mmc/mmc_protocol.c 2004-08-21 21:14:24.000000000 +0300
+++ kernel/drivers/mmc/mmc_protocol.c 2005-06-09 09:51:01.000000000 +0300
@@ -65,10 +65,12 @@
/* Fix the clock rate */
rate = mmc_tran_speed(dev->slot[slot].csd.tran_speed);
MMC_DEBUG(2,"==> mmc_configure_card (rate= %d) ",rate);
+ /* Trust the value reported by card
if ( rate < MMC_CLOCK_SLOW )
rate = MMC_CLOCK_SLOW;
if ( rate > MMC_CLOCK_FAST )
rate = MMC_CLOCK_FAST;
+ */
dev->sdrive->set_clock(rate);
diff -r -u kernel.org/drivers/mmc/mmc_samsung.c kernel/drivers/mmc/mmc_samsung.c
--- kernel.org/drivers/mmc/mmc_samsung.c 2004-06-23 02:12:06.000000000 +0300
+++ kernel/drivers/mmc/mmc_samsung.c 2005-06-09 10:26:11.000000000 +0300
@@ -317,10 +317,12 @@
int prescaler = 0;
/* Does not seem to work consistently if clock rate is above 10000000 */
+ /* Experimental - trust the value reported by card itself
if ( 10000000 < rate )
{
rate = 10000000;
}
+ */
prescaler = (2*PCLK)/(rate) - 1;
retval = mmc_s3c_stop_clock();
if ( retval ) return retval;
@@ -689,6 +691,7 @@
static void mmc_s3c_send_command (struct mmc_request * request)
{
int retval;
+ int clock;
/*
MMC_DEBUG(2," rINTMSK 0x%08X
rINTMOD 0x%08X
@@ -718,7 +721,16 @@
else {
retval = mmc_s3c_exec_command(request);
MMC_DEBUG(2," retval 0x%08X ",retval);
-
+ if(retval == MMC_ERROR_TIMEOUT) {
+ MMC_DEBUG(2," timed out, trying again at 600kHz");
+ request->result = MMC_NO_RESPONSE;
+ clock = g_s3c_mmc_data.clock; /* Save value */
+ mmc_s3c_adjust_clock(600000);
+ retval = mmc_s3c_exec_command(request);
+ MMC_DEBUG(2," retval 0x%08X ",retval);
+ mmc_s3c_adjust_clock(clock);
+ }
+
#if 0
if ( retval) {
// g_s3c_statistics.mmc_error++;
@@ -1165,7 +1177,9 @@
}
/* It is impossible to get both response and data */
if ( sd->request->nob ) {
- msk_reg = S3C_RX_FIFO_LAST_DATA_INT_ON | S3C_RX_FIFO_FULL_INT_ON;
+ msk_reg = S3C_RX_FIFO_LAST_DATA_INT_ON | S3C_RX_FIFO_FULL_INT_ON
+ |S3C_DATA_TIMEOUT_INT_ON;
+
MMC_DEBUG(2,": read SDIIMSK mask=0x%08x",rSDIIMSK);
// mod_timer( &sd->irq_timer, jiffies + MMC_IRQ_TIMEOUT);
// mmc_s3c_start_clock(); /* redundancy ? */
@@ -1253,6 +1267,11 @@
MMC_DEBUG(2, " rSDIIMSK 0x%08X cmd 0x%08X data 0x%08X fifo 0x%08X",rSDIIMSK,status[0],status[1],status[2]);
MMC_DEBUG(2, " rSDICON 0x%08X CCON 0x%08X DCONdata 0x%08X ",rSDICON,rSDICCON,rSDIDCON);
+ /* Clear the interrupt. Must write a one to the src pending register
+ then the interrupt pending register. */
+ h5400_asic_write_register (H5400_ASIC_IC_SRCPND, _H5400_ASIC_IC_INT_SD);
+ h5400_asic_write_register (H5400_ASIC_IC_INTPND, _H5400_ASIC_IC_INT_SD);
+
/* this can happen if there is an old interrupt hanging around when the irq is registered */
if (sd->request == NULL) {
printk ("ignoring mmc irq with null request\n");
@@ -1272,11 +1291,6 @@
mmc_s3c_split_status( sd, status, 0 );
- /* Clear the interrupt. Must write a one to the src pending register
- then the interrupt pending register. */
- h5400_asic_write_register (H5400_ASIC_IC_SRCPND, _H5400_ASIC_IC_INT_SD);
- h5400_asic_write_register (H5400_ASIC_IC_INTPND, _H5400_ASIC_IC_INT_SD);
-
/* Enable the irq */
enable_irq( irq );
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
The sd/mmc driver of linux 2.4.20 , it is much better than the one form samsung (good performance)
资源详情
资源评论
资源推荐
收起资源包目录
mmc_2440_handheld.org.rar (26个子文件)
mmc_2440_handheld.org
mmc_media.c 14KB
mmc_common.h 1KB
mmc_core.c 26KB
mmc_samsung.o 162KB
mmc_ll.h 3KB
Config.in 839B
mmc_protocol.h 10KB
mmc_core.h 2KB
mmc_s3c2440.c 5KB
sdi_reg_s3c2440.h 8KB
mmc_s3c2440.c.bak 5KB
mmc_protocol.c 14KB
mmc_base.o 486KB
mmc_core.o 176KB
mmc_samsung.h 1KB
mmc_samsung.c 42KB
sdi_reg_s3c2440.h.bak 8KB
mmc_samsung.c.bak 42KB
Makefile 554B
mmc_media.h 2KB
mmc_protocol.o 151KB
mmc_protocol.c.bak 14KB
mmc_media.o 161KB
patch_doc.txt 6KB
mmc_s3c2440.o 135KB
www.pudn.com.txt 218B
共 26 条
- 1
寒泊
- 粉丝: 75
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0