/* * Card detection callback from host. */ static void mmc_detect(struct mmc_host *host) { int err = 0; BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); if (host->card->err_count >= ERR_TRIGGER_REINIT) err = mmc_init_card(host, host->ocr, host->card); /* * Just check if our card has been removed. */ if (!err) err = mmc_send_status(host->card, NULL); mmc_release_host(host); if (err) { mmc_remove(host); mmc_claim_host(host); mmc_detach_bus(host); mmc_release_host(host); } }
static void mmc_power_restore(struct mmc_host *host) { host->card->state &= ~MMC_STATE_HIGHSPEED; mmc_claim_host(host); mmc_init_card(host, host->ocr, host->card); mmc_release_host(host); }
/* * Starting point for MMC card init. */ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) { int err; BUG_ON(!host); BUG_ON(!host->claimed); mmc_attach_bus(host, &mmc_ops); /* * Sanity check the voltages that the card claims to * support. */ if (ocr & 0x7F) { printk(KERN_WARNING "%s: card claims to support voltages " "below the defined range. These will be ignored.\n", mmc_hostname(host)); ocr &= ~0x7F; } host->ocr = mmc_select_voltage(host, ocr); /* * Can we support the voltage of the card? */ if (!host->ocr) { err = -EINVAL; goto err; } /* * Detect and init the card. */ err = mmc_init_card(host, host->ocr, NULL); if (err != MMC_ERR_NONE) goto err; mmc_release_host(host); err = mmc_add_card(host->card); if (err) goto remove_card; return 0; remove_card: mmc_remove_card(host->card); host->card = NULL; mmc_claim_host(host); err: mmc_detach_bus(host); mmc_release_host(host); printk(KERN_ERR "%s: error %d whilst initialising MMC card\n", mmc_hostname(host), err); return 0; }
static int mmc_power_restore(struct mmc_host *host) { int ret; host->card->state &= ~MMC_STATE_HIGHSPEED; mmc_claim_host(host); ret = mmc_init_card(host, host->ocr, host->card); mmc_release_host(host); return ret; }
/* * Allocate a new MMC card */ struct mmc_card *mmc_alloc_card(struct mmc_host *host) { struct mmc_card *card; card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); if (!card) return ERR_PTR(-ENOMEM); mmc_init_card(card, host); return card; }
/* * Resume callback from host. * * This function tries to determine if the same card is still present * and, if so, restore all state to it. */ static int mmc_resume(struct mmc_host *host) { int err; BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); err = mmc_init_card(host, host->ocr, host->card); mmc_release_host(host); return err; }
int mmc_boot_up_test(int id, int reset, u32 freq, int in_idle) { int err = MMC_ERR_FAILED; struct mmc_host *host; struct mmc_card *card; host = mmc_get_host(id); card = mmc_get_card(id); mmc_init_host(host, id); if (in_idle) { printf("[EMMC] Card is in idle mode \n"); /* card in idle mode */ //mmc_go_idle(host); mmc_init_card(host, card); /* note: requires delay before issue boot reset command */ mdelay(5); } else { /* card not in idle mode */ printf("[EMMC] Card is not in idle mode \n"); } msdc_emmc_boot_reset(host, reset); err = msdc_emmc_boot_start(host, freq, 0, EMMC_BOOT_RST_CMD_MODE, 0); if (err) { printf("[EMMC] Boot Error: %d\n", err); goto done; } err = msdc_emmc_boot_read(host, 128 * 1024, MMC_BUF_ADDR); msdc_emmc_boot_stop(host, EMMC_BOOT_RST_CMD_MODE); if (err) { printf("[EMMC] Boot Read Error: %d\n", err); goto done; } done: if (!err) { int i, j; char *buf = (char*)MMC_BUF_ADDR; for (i = 0; i < 16; i++) { for (j = 0; j < MMC_BLOCK_SIZE; j++) { if (j % 16 == 0) printf("\n%xh: ", i * MMC_BLOCK_SIZE + j); printf("%x ", buf[j]); } printf("\n"); buf += MMC_BLOCK_SIZE; } } return err; }
static void mmc_power_restore(struct mmc_host *host) { //[NAGSM_Android_HDLNC_SDcard_shinjonghyun_20100504 : mutual exclusion when MoviNand and SD cardusing using this funtion mutex_lock(&host->carddetect_lock); //]NAGSM_Android_HDLNC_SDcard_shinjonghyun_20100504 : mutual exclusion when MoviNand and SD cardusing using this funtion host->card->state &= ~MMC_STATE_HIGHSPEED; mmc_claim_host(host); mmc_init_card(host, host->ocr, host->card); mmc_release_host(host); //[NAGSM_Android_HDLNC_SDcard_shinjonghyun_20100504 : mutual exclusion when MoviNand and SD cardusing using this funtion mutex_unlock(&host->carddetect_lock); //]NAGSM_Android_HDLNC_SDcard_shinjonghyun_20100504 : mutual exclusion when MoviNand and SD cardusing using this funtion }
/* * Resume callback from host. * * This function tries to determine if the same card is still present * and, if so, restore all state to it. */ static int mmc_resume(struct mmc_host *host) { int err; BUG_ON(!host); BUG_ON(!host->card); pr_info("%s: @%s", mmc_hostname(host), __func__);//add by yansen 20120607 for mmc0: CMD5: Request timeout mmc_claim_host(host); err = mmc_init_card(host, host->ocr, host->card); mmc_release_host(host); return err; }
int MMC_disk_initialize() { // taken from http://elm-chan.org/fsw/ff/en/dinit.html // (and similar on-disk docs) mmc_configure_spi(); mmc_init_card(); mmc_configure_card(); //mmc_read_stats(buffer); // we should do something intelligent with the status, but // not for now MMC_IS_INIT = MMC_INIT_YES; return 1; }
/* * Resume callback from host. * * This function tries to determine if the same card is still present * and, if so, restore all state to it. */ static int mmc_resume(struct mmc_host *host) { int err; BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); if (mmc_card_is_sleep(host->card)) { err = mmc_card_awake(host); mmc_card_clr_sleep(host->card); } else err = mmc_init_card(host, host->ocr, host->card); mmc_release_host(host); return err; }
/* * Resume callback from host. * * This function tries to determine if the same card is still present * and, if so, restore all state to it. */ static int mmc_resume(struct mmc_host *host) { int err; BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); err = mmc_init_card(host, host->ocr, host->card); mmc_release_host(host); #if 0 if (err) mmc_err_with_deferred_resume(host); #endif return err; }
/* * Resume callback from host. * * This function tries to determine if the same card is still present * and, if so, restore all state to it. */ static int mmc_resume(struct mmc_host *host) { int err; //[NAGSM_Android_HDLNC_SDcard_shinjonghyun_20100504 : mutual exclusion when MoviNand and SD cardusing using this funtion mutex_lock(&host->carddetect_lock); //]NAGSM_Android_HDLNC_SDcard_shinjonghyun_20100504 : mutual exclusion when MoviNand and SD cardusing using this funtion BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); err = mmc_init_card(host, host->ocr, host->card); mmc_release_host(host); //[NAGSM_Android_HDLNC_SDcard_shinjonghyun_20100504 : mutual exclusion when MoviNand and SD cardusing using this funtion mutex_unlock(&host->carddetect_lock); //]NAGSM_Android_HDLNC_SDcard_shinjonghyun_20100504 : mutual exclusion when MoviNand and SD cardusing using this funtion return err; }
/* * Resume callback from host. * * This function tries to determine if the same card is still present * and, if so, restore all state to it. */ static void mmc_resume(struct mmc_host *host) { int err; BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); err = mmc_init_card(host, host->ocr, host->card); mmc_release_host(host); if (err) { mmc_remove(host); mmc_claim_host(host); mmc_detach_bus(host); mmc_release_host(host); } }
/* * Starting point for MMC card init. */ int mmc_attach_mmc(struct mmc_host *host) { int err; u32 ocr; BUG_ON(!host); WARN_ON(!host->claimed); err = mmc_send_op_cond(host, 0, &ocr); if (err) return err; mmc_attach_bus_ops(host); /* * We need to get OCR a different way for SPI. */ if (mmc_host_is_spi(host)) { err = mmc_spi_read_ocr(host, 1, &ocr); if (err) goto err; } /* * Sanity check the voltages that the card claims to * support. */ if (ocr & 0x7F) { printk(KERN_WARNING "%s: card claims to support voltages " "below the defined range. These will be ignored.\n", mmc_hostname(host)); ocr &= ~0x7F; } host->ocr = mmc_select_voltage(host, ocr); /* * Can we support the voltage of the card? */ if (!host->ocr) { err = -EINVAL; goto err; } /* * Detect and init the card. */ err = mmc_init_card(host, host->ocr, NULL); if (err) goto err; mmc_release_host(host); err = mmc_add_card(host->card); mmc_claim_host(host); if (err) goto remove_card; return 0; remove_card: mmc_release_host(host); mmc_remove_card(host->card); mmc_claim_host(host); host->card = NULL; err: mmc_detach_bus(host); printk(KERN_ERR "%s: error %d whilst initialising MMC card\n", mmc_hostname(host), err); return err; }
/* * Starting point for MMC card init. */ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) { int err; int i = 0; BUG_ON(!host); WARN_ON(!host->claimed); mmc_attach_bus_ops(host); /* * We need to get OCR a different way for SPI. */ if (mmc_host_is_spi(host)) { err = mmc_spi_read_ocr(host, 1, &ocr); if (err) goto err; } /* * Sanity check the voltages that the card claims to * support. */ if (ocr & 0x7F) { printk(KERN_WARNING "%s: card claims to support voltages " "below the defined range. These will be ignored.\n", mmc_hostname(host)); ocr &= ~0x7F; } host->ocr = mmc_select_voltage(host, ocr); /* * Can we support the voltage of the card? */ if (!host->ocr) { err = -EINVAL; goto err; } /* * Detect and init the card. */ err = mmc_init_card(host, host->ocr, NULL); if (err) goto err; /* WA : Lock/Unlock CMD in case of 32nm iNAND */ /*check iNAND*/ if (host->card->cid.manfid == 0x45 || host->card->cid.manfid == 0x02) /*check 32nm*/ if (!(host->card->ext_csd.hpi & 0x1)) { printk(KERN_DEBUG "%s: Lock-unlock started, MID=0x%x, HPI=0x%x\n", __func__, host->card->cid.manfid, host->card->ext_csd.hpi); for (i = 0 ; i < 50 ; i++) { if (mmc_send_lock_cmd(host, 1)) { printk(KERN_ERR "%s: eMMC lock CMD is failed.\n", mmc_hostname(host)); goto remove_card; } if (mmc_send_lock_cmd(host, 0)) { printk(KERN_ERR "%s: eMMC unlock CMD is failed.\n", mmc_hostname(host)); goto remove_card; } } printk(KERN_DEBUG "%s:COMPLETED\n",__func__); } mmc_release_host(host); err = mmc_add_card(host->card); if (err) goto remove_card; return 0; remove_card: mmc_remove_card(host->card); host->card = NULL; mmc_claim_host(host); err: mmc_detach_bus(host); mmc_release_host(host); printk(KERN_ERR "%s: error %d whilst initialising MMC card\n", mmc_hostname(host), err); return err; }
int mmc_test_mem_card(struct mmc_test_config *cfg) { int id, count, forever; int ret, chk_result, tid = 0, result = 0; unsigned int chunks, chunk_blks, left_blks, pass = 0, fail = 0; unsigned int total_blks; unsigned int i, j; unsigned int blksz; unsigned int clkhz; char pattern = 0; char *buf; unsigned long blknr; struct mmc_host *host; struct mmc_card *card; id = cfg->id; count = cfg->count; buf = cfg->buf; blknr = cfg->blknr; blksz = cfg->blksz; chk_result = cfg->chk_result; chunk_blks = cfg->chunk_blks; total_blks = (cfg->total_size + blksz - 1) / blksz; forever = (count == -1) ? 1 : 0; host = mmc_get_host(id); card = mmc_get_card(id); while (forever || count--) { printf("[TST] ==============================================\n"); printf("[TST] BEGIN: %d/%d, No Stop(%d)\n", (cfg->count != -1) ? cfg->count - count : 0, (cfg->count != -1) ? cfg->count : 0, forever); printf("[TST] ----------------------------------------------\n"); printf("[TST] Mode : %d\n", cfg->mode); printf("[TST] Clock : %d kHz\n", cfg->clock / 1000); printf("[TST] BusWidth: %d bits\n", cfg->buswidth); printf("[TST] BurstSz : %d bytes\n", 0x1 << cfg->burstsz); printf("[TST] BlkAddr : %xh\n", blknr); printf("[TST] BlkSize : %dbytes\n", blksz); printf("[TST] TstBlks : %d\n", total_blks); #if defined(BB_MT6575) printf("[TST] AutoCMD : 12(%d), 23(%d)\n", (cfg->autocmd & MSDC_AUTOCMD12) ? 1 : 0, (cfg->autocmd & MSDC_AUTOCMD23) ? 1 : 0); #endif printf("[TST] ----------------------------------------------\n"); if (mmc_init_host(host, id) != 0) { result = -__LINE__; goto failure; } if (mmc_init_card(host, card) != 0) { result = -__LINE__; goto failure; } #if defined(BB_MT6575) msdc_set_dma(host, (u8)cfg->burstsz, (u32)cfg->flags); msdc_set_autocmd(host, cfg->autocmd, 1); #endif /* change uhs-1 mode */ #if 0 if (mmc_card_uhs1(card)) { if (mmc_switch_uhs1(host, card, cfg->uhsmode) != 0) { result = -__LINE__; goto failure; } } #endif /* change clock */ if (cfg->clock) { clkhz = card->maxhz < cfg->clock ? card->maxhz : cfg->clock; mmc_set_clock(host, mmc_card_ddr(card), clkhz); } if (mmc_card_sd(card) && cfg->buswidth == HOST_BUS_WIDTH_8) { printf("[TST] SD card doesn't support 8-bit bus width (SKIP)\n"); result = MMC_ERR_NONE; } if (mmc_set_bus_width(host, card, cfg->buswidth) != 0) { result = -__LINE__; goto failure; } /* cmd16 is illegal while card is in ddr mode */ if (!(mmc_card_mmc(card) && mmc_card_ddr(card))) { if (mmc_set_blk_length(host, blksz) != 0) { result = -__LINE__; goto failure; } } #if defined(BB_MT6575) if (cfg->piobits) { printf("[TST] PIO bits: %d\n", cfg->piobits); msdc_set_pio_bits(host, cfg->piobits); } #endif tid = result = 0; if (mmc_erase_start(card, blknr * blksz) != MMC_ERR_NONE) { result = -__LINE__; goto failure; } if (mmc_erase_end(card, (blknr + total_blks) * blksz) != MMC_ERR_NONE) { result = -__LINE__; goto failure; } if (mmc_erase(card, MMC_ERASE_NORMAL) != MMC_ERR_NONE) { result = -__LINE__; goto failure; } printf("[TST] 0x%x - 0x%x Erased\n", blknr * blksz, (blknr + total_blks) * blksz); mmc_send_status(host, card, &status); if (cfg->tst_single) { /* single block write */ for (i = 0; i < total_blks; i++) { pattern = (i + count) % 256; memset(buf, pattern, blksz); ret = mmc_block_write(id, blknr + i, 1, (unsigned long*)buf); if (ret != MMC_ERR_NONE) { printf("test single block write failed (%d)\n", i); result = -__LINE__; goto failure; } } printf(TC_MSG, host->id, result == 0 ? "PASS" : "FAIL", tid++, "test single block write\n"); if (result) break; /* single block read */ for (i = 0; i < total_blks && !result; i++) { pattern = (i + count) % 256; /* populate buffer with different pattern */ memset(buf, pattern + 1, blksz); ret = mmc_block_read(id, blknr + i, 1, (unsigned long*)buf); if (ret != MMC_ERR_NONE) { result = -__LINE__; goto failure; } if (chk_result) { for (j = 0; j < blksz; j++) { if (buf[j] != pattern) { result = -__LINE__; goto failure; } } } } printf(TC_MSG, host->id, result == 0 ? "PASS" : "FAIL", tid++, "test single block read\n"); if (result) { printf("[SD%d]\t\tread back pattern(0x%.2x) failed\n", id, pattern); goto failure; } } mmc_send_status(host, card, &status); if (cfg->tst_multiple) { /* multiple block write */ chunks = total_blks / chunk_blks; left_blks = total_blks % chunk_blks; for (i = 0; i < chunks; i++) { pattern = (i + count) % 256; memset(buf, pattern, blksz * chunk_blks); ret = mmc_block_write(id, blknr + i * chunk_blks, chunk_blks, (unsigned long*)buf); if (ret != MMC_ERR_NONE) { result = -__LINE__; goto failure; } } if (!result && left_blks) { pattern = (i + count) % 256; memset(buf, pattern, blksz * left_blks); ret = mmc_block_write(id, blknr + chunks * chunk_blks, left_blks, (unsigned long*)buf); if (ret != MMC_ERR_NONE) { result = -__LINE__; goto failure; } } printf(TC_MSG, host->id, result == 0 ? "PASS" : "FAIL", tid++, "test multiple block write\n"); if (result) goto failure; /* multiple block read */ for (i = 0; i < chunks; i++) { pattern = (i + count) % 256; /* populate buffer with different pattern */ memset(buf, pattern + 1, blksz); ret = mmc_block_read(id, blknr + i * chunk_blks, chunk_blks, (unsigned long*)buf); if (ret != MMC_ERR_NONE) { printf("[SD%d]\t\tread %d blks failed(ret = %d blks)\n", host->id, chunk_blks, ret); result = -__LINE__; goto failure; } if (chk_result) { for (j = 0; j < chunk_blks * blksz; j++) { if (buf[j] == pattern) continue; result = -__LINE__; printf("[SD%d]\t\t%xh = %x (!= %x)\n", host->id, blknr + i * chunk_blks + j, buf[j], pattern); goto failure; } } } if (!result && left_blks) { pattern = i % 256; /* populate buffer with different pattern */ memset(buf, pattern + 1, blksz); ret = mmc_block_read(id, blknr + chunks * chunk_blks, left_blks, (unsigned long*)buf); if (ret != MMC_ERR_NONE) { printf("[SD%d]\t\tread %d blks failed(ret = %d blks)\n", host->id, left_blks, ret); result = -__LINE__; goto failure; } if (chk_result) { for (j = 0; j < left_blks * blksz; j++) { if (buf[j] == pattern) continue; printf("[SD%d]\t\t%xh = %x (!= %x)\n", host->id, blknr + chunks * chunk_blks + j, buf[j], pattern); result = -__LINE__; goto failure; } } } printf(TC_MSG, host->id, result == 0 ? "PASS" : "FAIL", tid++, "test multiple block read\n"); if (result) goto failure; } mmc_send_status(host, card, &status); if (cfg->tst_interleave) { /* multiple block write */ chunks = total_blks / chunk_blks; left_blks = total_blks % chunk_blks; for (i = 0; i < chunks; i++) { pattern = (i + count) % 256; memset(buf, pattern, blksz * chunk_blks); ret = mmc_block_write(id, blknr + i * chunk_blks, chunk_blks, (unsigned long*)buf); if (ret != MMC_ERR_NONE) { result = -__LINE__; goto failure; } /* populate buffer with different pattern */ memset(buf, pattern + 1, blksz * chunk_blks); ret = mmc_block_read(id, blknr + i * chunk_blks, chunk_blks, (unsigned long*)buf); if (ret != MMC_ERR_NONE) { result = -__LINE__; goto failure; } if (chk_result) { for (j = 0; j < chunk_blks * blksz; j++) { if (buf[j] == pattern) continue; result = -__LINE__; goto failure; } } } if (!result && left_blks) { pattern = (i + count) % 256; memset(buf, pattern, blksz * left_blks); ret = mmc_block_write(id, blknr + chunks * chunk_blks, left_blks, (unsigned long*)buf); if (ret != MMC_ERR_NONE) { result = -__LINE__; goto failure; } /* populate buffer with different pattern */ memset(buf, pattern + 1, blksz * left_blks); ret = mmc_block_read(id, blknr + chunks * chunk_blks, left_blks, (unsigned long*)buf); if (ret != MMC_ERR_NONE) { result = -__LINE__; break; } if (chk_result) { for (j = 0; j < left_blks * blksz; j++) { if (buf[j] == pattern) continue; result = -__LINE__; goto failure; } } } printf(TC_MSG, host->id, result == 0 ? "PASS" : "FAIL", tid++, "test multiple block interleave write-read\n"); if (result) goto failure; } if (cfg->desc) { printf("[TST] ----------------------------------------------\n"); printf("[TST] Report - %s \n", cfg->desc); printf("[TST] ----------------------------------------------\n"); } mmc_prof_dump(id); failure: if (result) { printf("[SD%d] mmc test failed (%d)\n", host->id, result); fail++; } else { pass++; } printf("[TST] ----------------------------------------------\n"); printf("[TST] Test Result: TOTAL(%d/%d), PASS(%d), FAIL(%d) \n", cfg->count - count, cfg->count, pass, fail); printf("[TST] ----------------------------------------------\n"); //mdelay(1000); } return result; }