From e1bc0be9f95559ae154d24b353e404c781798da1 Mon Sep 17 00:00:00 2001 From: Andy Green Date: Fri, 25 Jul 2008 23:06:20 +0100 Subject: [PATCH] debug-add-glamo-drive-strength-module-param.patch Suggested-by: Werner Almesberger 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 --- 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 93f4074..4615033 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); } -- 1.5.6.3