Commit aac4b69b2c916736911976562bfc0cb4bfd26b2f
Committed by
Andreas Bießmann
1 parent
248020734b
Exists in
master
and in
53 other branches
mmc: atmel_mci: using IP version for different setting
Using IP version for different setting - Higher version supports 8bit mode - Higher version bus width setting is different Signed-off-by: Bo Shen <voice.shen@atmel.com> Signed-off-by: Andreas Bießmann <andreas.devel@googlemail.com>
Showing 2 changed files with 40 additions and 4 deletions Side-by-side Diff
drivers/mmc/gen_atmel_mci.c
... | ... | @@ -50,6 +50,12 @@ |
50 | 50 | |
51 | 51 | static int initialized = 0; |
52 | 52 | |
53 | +/* Read Atmel MCI IP version */ | |
54 | +static unsigned int atmel_mci_get_version(struct atmel_mci *mci) | |
55 | +{ | |
56 | + return readl(&mci->version) & 0x00000fff; | |
57 | +} | |
58 | + | |
53 | 59 | /* |
54 | 60 | * Print command and status: |
55 | 61 | * |
... | ... | @@ -297,7 +303,9 @@ |
297 | 303 | static void mci_set_ios(struct mmc *mmc) |
298 | 304 | { |
299 | 305 | atmel_mci_t *mci = (atmel_mci_t *)mmc->priv; |
300 | - int busw = (mmc->bus_width == 4) ? 1 : 0; | |
306 | + int bus_width = mmc->bus_width; | |
307 | + unsigned int version = atmel_mci_get_version(mci); | |
308 | + int busw; | |
301 | 309 | |
302 | 310 | /* Set the clock speed */ |
303 | 311 | mci_set_mode(mmc, mmc->clock, MMC_DEFAULT_BLKLEN); |
304 | 312 | |
... | ... | @@ -305,9 +313,26 @@ |
305 | 313 | /* |
306 | 314 | * set the bus width and select slot for this interface |
307 | 315 | * there is no capability for multiple slots on the same interface yet |
308 | - * Bitfield SCDBUS needs to be expanded to 2 bits for 8-bit buses | |
309 | 316 | */ |
310 | - writel(MMCI_BF(SCDBUS, busw) | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); | |
317 | + if ((version & 0xf00) >= 0x300) { | |
318 | + switch (bus_width) { | |
319 | + case 8: | |
320 | + busw = 3; | |
321 | + break; | |
322 | + case 4: | |
323 | + busw = 2; | |
324 | + break; | |
325 | + default: | |
326 | + busw = 0; | |
327 | + break; | |
328 | + } | |
329 | + | |
330 | + writel(busw << 6 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); | |
331 | + } else { | |
332 | + busw = (bus_width == 4) ? 1 : 0; | |
333 | + | |
334 | + writel(busw << 7 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); | |
335 | + } | |
311 | 336 | } |
312 | 337 | |
313 | 338 | /* Entered into mmc structure during driver init */ |
314 | 339 | |
... | ... | @@ -340,9 +365,12 @@ |
340 | 365 | int atmel_mci_init(void *regs) |
341 | 366 | { |
342 | 367 | struct mmc *mmc = malloc(sizeof(struct mmc)); |
368 | + struct atmel_mci *mci; | |
369 | + unsigned int version; | |
343 | 370 | |
344 | 371 | if (!mmc) |
345 | 372 | return -1; |
373 | + | |
346 | 374 | strcpy(mmc->name, "mci"); |
347 | 375 | mmc->priv = regs; |
348 | 376 | mmc->send_cmd = mci_send_cmd; |
... | ... | @@ -353,7 +381,13 @@ |
353 | 381 | |
354 | 382 | /* need to be able to pass these in on a board by board basis */ |
355 | 383 | mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; |
356 | - mmc->host_caps = MMC_MODE_4BIT; | |
384 | + mci = (struct atmel_mci *)mmc->priv; | |
385 | + version = atmel_mci_get_version(mci); | |
386 | + if ((version & 0xf00) >= 0x300) | |
387 | + mmc->host_caps = MMC_MODE_8BIT; | |
388 | + | |
389 | + mmc->host_caps |= MMC_MODE_4BIT; | |
390 | + | |
357 | 391 | /* |
358 | 392 | * min and max frequencies determined by |
359 | 393 | * max and min of clock divider |