[PATCH] debug-add-glamo-drive-strength-module-param.patch

Sean McNeil sean at mcneil.com
Mon Jul 21 02:03:19 CEST 2008


I just thought of a condition that isn't well tested here. It is quite 
possible that my sdcard corruption occurs on suspend or partial suspend. 
Is a block guaranteed to have been written and settled before a suspend 
can take place? Is there any confirmation of a write completing before 
the write returns? How about settle time for a write? Is there one for 
memory cards?

Andy Green wrote:
> Suggested-by: Werner Almesberger <werner at openmoko.org>
>
> This patch allows users to control two additional settings
> in Glamo MCI driver from kernel commandline or module
> parameters.
>
>
> First is Glamo drive strength on SD IOs including CLK.
> This ranges from 0 (weakest) to 3 (strongest).
>
> echo 0 > /sys/module/glamo_mci/parameters/sd_drive
>
> (Changes to this take effect on next SD Card transaction)
>
> or, from kernel commandline
>
> glamo_mci.sd_drive=0
>
> On tests here with 0 strength, communication to SD card
> (shipped 512MB Sandisk) seemed fine, and a dd of 10MB
> urandom had the same md5 when written to cache as after
> a reboot.  I set the default to 2.
>
>
> Second is whether we allow SD_CLK when the SD interface
> is idle.
>
> # stop the clock when we are idle (default)
> echo 0 > /sys/module/glamo_mci/parameters/sd_idleclk
>
> # run the SD clock all the time
> echo 1 > /sys/module/glamo_mci/parameters/sd_idleclk
>
> (changes take effect on next SD Card transaction)
>
> >From kernel commandline, eg:
>
> glamo_mci.sd_idleclk=1
>
> Normally you don't want to run the SD Clock all the time.
>
>
> Signed-off-by: Andy Green <andy at openmoko.com>
> ---
>
>  drivers/mfd/glamo/glamo-mci.c |   59 +++++++++++++++++++++++++++++++----------
>  1 files changed, 45 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c
> index 2318e6f..6585821 100644
> --- a/drivers/mfd/glamo/glamo-mci.c
> +++ b/drivers/mfd/glamo/glamo-mci.c
> @@ -56,6 +56,32 @@ static void glamo_mci_send_request(struct mmc_host *mmc);
>  static int sd_max_clk = 50000000 / 3;
>  module_param(sd_max_clk, int, 0644);
>  
> +/*
> + * SD Signal drive strength
> + *
> + * you can override this on kernel commandline using
> + *
> + *   glamo_mci.sd_drive=0
> + *
> + * for example
> + */
> +
> +static int sd_drive = 2;
> +module_param(sd_drive, int, 0644);
> +
> +/*
> + * SD allow SD clock to run while idle
> + *
> + * you can override this on kernel commandline using
> + *
> + *   glamo_mci.sd_idleclk=0
> + *
> + * for example
> + */
> +
> +static int sd_idleclk = 0; /* disallow idle clock by default */
> +module_param(sd_idleclk, int, 0644);
> +
>  
>  
>  unsigned char CRC7(u8 * pu8, int cnt)
> @@ -239,7 +265,9 @@ static int __glamo_mci_set_card_clock(struct glamo_mci_host *host, int freq,
>  		if (division)
>  			*division = 0xff;
>  
> -		__glamo_mci_fix_card_div(host, -1); /* clock off */
> +		if (!sd_idleclk)
> +			/* clock off */
> +			__glamo_mci_fix_card_div(host, -1);
>  	}
>  
>  	return real_rate;
> @@ -294,8 +322,9 @@ static void glamo_mci_irq(unsigned int irq, struct irq_desc *desc)
>  		host->cmd_is_stop = 0;
>  	}
>  
> -	/* clock off */
> -	__glamo_mci_fix_card_div(host, -1);
> +	if (!sd_idleclk)
> +		/* clock off */
> +		__glamo_mci_fix_card_div(host, -1);
>  
>  done:
>  	host->complete_what = COMPLETION_NONE;
> @@ -428,12 +457,10 @@ static int glamo_mci_send_command(struct glamo_mci_host *host,
>  	} else
>  		writew(0xfff, host->base + GLAMO_REG_MMC_TIMEOUT);
>  
> -	/* Generate interrupt on txfer; drive strength max */
> -	writew_dly((readw_dly(host->base + GLAMO_REG_MMC_BASIC) & 0xfe) |
> +	/* Generate interrupt on txfer */
> +	writew_dly((readw_dly(host->base + GLAMO_REG_MMC_BASIC) & 0x3e) |
>  		   0x0800 | GLAMO_BASIC_MMC_NO_CLK_RD_WAIT |
> -		   GLAMO_BASIC_MMC_EN_COMPL_INT |
> -		   GLAMO_BASIC_MMC_EN_DR_STR0 |
> -		   GLAMO_BASIC_MMC_EN_DR_STR1,
> +		   GLAMO_BASIC_MMC_EN_COMPL_INT | (sd_drive << 6),
>  		   host->base + GLAMO_REG_MMC_BASIC);
>  
>  	/* send the command out on the wire */
> @@ -620,8 +647,9 @@ done:
>  	host->mrq = NULL;
>  	mmc_request_done(host->mmc, cmd->mrq);
>  bail:
> -	/* stop the clock to card */
> -	__glamo_mci_fix_card_div(host, -1);
> +	if (!sd_idleclk)
> +		/* stop the clock to card */
> +		__glamo_mci_fix_card_div(host, -1);
>  }
>  
>  static void glamo_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
> @@ -687,8 +715,9 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>  	host->real_rate = __glamo_mci_set_card_clock(host, ios->clock, &div);
>  	host->clk_div = div;
>  
> -	/* stop the clock to card, because we are idle until transfer */
> -	__glamo_mci_fix_card_div(host, -1);
> +	if (!sd_idleclk)
> +		/* stop the clock to card, because we are idle until transfer */
> +		__glamo_mci_fix_card_div(host, -1);
>  
>  	if ((ios->power_mode == MMC_POWER_ON) ||
>  	    (ios->power_mode == MMC_POWER_UP)) {
> @@ -705,8 +734,10 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>  	if (host->bus_width == MMC_BUS_WIDTH_4)
>  		n = GLAMO_BASIC_MMC_EN_4BIT_DATA;
>  	writew_dly((readw_dly(host->base + GLAMO_REG_MMC_BASIC) &
> -					  (~GLAMO_BASIC_MMC_EN_4BIT_DATA)) | n,
> -					      host->base + GLAMO_REG_MMC_BASIC);
> +					  (~(GLAMO_BASIC_MMC_EN_4BIT_DATA |
> +					     GLAMO_BASIC_MMC_EN_DR_STR0 |
> +					     GLAMO_BASIC_MMC_EN_DR_STR1))) | n |
> +			       sd_drive << 6, host->base + GLAMO_REG_MMC_BASIC);
>  }
>  
>  
>
>
>
>   




More information about the openmoko-kernel mailing list