Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 31650
b: refs/heads/master
c: 1c8cde9
h: refs/heads/master
v: v3
  • Loading branch information
Pierre Ossman authored and Russell King committed Jul 2, 2006
1 parent a5aeacd commit 4c562bc
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e16514d8d86ecbde18a2a7495cf028861b34c157
refs/heads/master: 1c8cde92fa5c57daa9ff58d970ca6374f8d484a2
47 changes: 44 additions & 3 deletions trunk/drivers/mmc/sdhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,6 @@ static void sdhci_init(struct sdhci_host *host)

writel(intmask, host->ioaddr + SDHCI_INT_ENABLE);
writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE);

/* This is unknown magic. */
writeb(0xE, host->ioaddr + SDHCI_TIMEOUT_CONTROL);
}

static void sdhci_activate_led(struct sdhci_host *host)
Expand Down Expand Up @@ -274,6 +271,8 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
{
u16 mode;
u8 count;
unsigned target_timeout, current_timeout;

WARN_ON(host->data);

Expand All @@ -287,6 +286,37 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
DBG("tsac %d ms nsac %d clk\n",
data->timeout_ns / 1000000, data->timeout_clks);

/* timeout in us */
target_timeout = data->timeout_ns / 1000 +
data->timeout_clks / host->clock;

/*
* Figure out needed cycles.
* We do this in steps in order to fit inside a 32 bit int.
* The first step is the minimum timeout, which will have a
* minimum resolution of 6 bits:
* (1) 2^13*1000 > 2^22,
* (2) host->timeout_clk < 2^16
* =>
* (1) / (2) > 2^6
*/
count = 0;
current_timeout = (1 << 13) * 1000 / host->timeout_clk;
while (current_timeout < target_timeout) {
count++;
current_timeout <<= 1;
if (count >= 0xF)
break;
}

if (count >= 0xF) {
printk(KERN_WARNING "%s: Too large timeout requested!\n",
mmc_hostname(host->mmc));
count = 0xE;
}

writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL);

mode = SDHCI_TRNS_BLK_CNT_EN;
if (data->blocks > 1)
mode |= SDHCI_TRNS_MULTI;
Expand Down Expand Up @@ -1096,6 +1126,17 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
}
host->max_clk *= 1000000;

host->timeout_clk =
(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
if (host->timeout_clk == 0) {
printk(KERN_ERR "%s: Hardware doesn't specify timeout clock "
"frequency.\n", host->slot_descr);
ret = -ENODEV;
goto unmap;
}
if (caps & SDHCI_TIMEOUT_CLK_UNIT)
host->timeout_clk *= 1000;

/*
* Set host parameters.
*/
Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/mmc/sdhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@
/* 3E-3F reserved */

#define SDHCI_CAPABILITIES 0x40
#define SDHCI_TIMEOUT_CLK_MASK 0x0000003F
#define SDHCI_TIMEOUT_CLK_SHIFT 0
#define SDHCI_TIMEOUT_CLK_UNIT 0x00000080
#define SDHCI_CLOCK_BASE_MASK 0x00003F00
#define SDHCI_CLOCK_BASE_SHIFT 8
#define SDHCI_CAN_DO_DMA 0x00400000
Expand Down Expand Up @@ -156,6 +159,7 @@ struct sdhci_host {
#define SDHCI_USE_DMA (1<<0)

unsigned int max_clk; /* Max possible freq (MHz) */
unsigned int timeout_clk; /* Timeout freq (KHz) */

unsigned int clock; /* Current clock (MHz) */
unsigned short power; /* Current voltage */
Expand Down

0 comments on commit 4c562bc

Please sign in to comment.