static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status) { unsigned int bus_speed = 0, timing = 0; int err; /* * If the host doesn't support any of the UHS-I modes, fallback on * default speed. */ if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))) return 0; if ((card->host->caps & MMC_CAP_UHS_SDR104) && (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) { bus_speed = UHS_SDR104_BUS_SPEED; timing = MMC_TIMING_UHS_SDR104; card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR; } else if ((card->host->caps & MMC_CAP_UHS_DDR50) && (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) { bus_speed = UHS_DDR50_BUS_SPEED; timing = MMC_TIMING_UHS_DDR50; card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR; } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR50)) { bus_speed = UHS_SDR50_BUS_SPEED; timing = MMC_TIMING_UHS_SDR50; card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR; } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) && (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) { bus_speed = UHS_SDR25_BUS_SPEED; timing = MMC_TIMING_UHS_SDR25; card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR; } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR12)) { bus_speed = UHS_SDR12_BUS_SPEED; timing = MMC_TIMING_UHS_SDR12; card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR; } card->sd_bus_speed = bus_speed; err = mmc_sd_switch(card, 1, 0, bus_speed, status); if (err) return err; if ((status[16] & 0xF) != bus_speed) { printk(KERN_WARNING "%s: Problem setting bus speed mode!\n", mmc_hostname(card->host)); } else { mmc_set_timing(card->host, timing); mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr); } return 0; }
void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) { DECLARE_COMPLETION_ONSTACK(complete); mrq->done_data = &complete; mrq->done = mmc_wait_done; do { mmc_start_request(host, mrq); wait_for_completion(&complete); /* * If CRC error happens, slow down the clock and resend the request */ if ((mrq->cmd->error == -EILSEQ) || (mrq->data && (mrq->data->error == -EILSEQ))) { /* * If the clock is too slow, the performance is very poor. * So, just return error. */ if (host->ios.clock <= 3000000) { printk(KERN_WARNING "SD clock is too slow!\n"); break; } printk(KERN_WARNING "%s: CRC error! slow the clock to %d\n", mmc_hostname(host), host->ios.clock/2); mmc_set_clock(host, host->ios.clock/2); } else { break; } } while (1); }
/** * mmc_switch - modify EXT_CSD register * @card: the MMC card associated with the data transfer * @set: cmd set values * @index: EXT_CSD register index * @value: value to program into EXT_CSD register * @timeout_ms: timeout (ms) for operation performed by register write, * timeout of zero implies maximum possible timeout * * Modifies the EXT_CSD register for selected card. */ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, unsigned int timeout_ms) { int err; struct mmc_command cmd = {0}; u32 status; BUG_ON(!card); BUG_ON(!card->host); cmd.opcode = MMC_SWITCH; cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | (index << 16) | (value << 8) | set; cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; cmd.cmd_timeout_ms = timeout_ms; err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); if (err) return err; /* Must check status to be sure of no errors */ do { /*The purpose of set clk here is to make 2x mode to reset the sample point * Because if switch to new timing mode,device's timing maybe change,so we * should reset the sample point to get new sample point * If our controller not use 2x mode,the change below will have no harm * */ mmc_set_clock(card->host,card->host->ios.clock); err = mmc_send_status(card, &status); if (err) return err; if (card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) break; if (mmc_host_is_spi(card->host)) break; } while (R1_CURRENT_STATE(status) == R1_STATE_PRG); if (mmc_host_is_spi(card->host)) { if (status & R1_SPI_ILLEGAL_COMMAND) return -EBADMSG; } else { if (status & 0xFDFFA000) pr_warning("%s: unexpected status %#x after " "switch", mmc_hostname(card->host), status); if (status & R1_SWITCH_ERROR) return -EBADMSG; } return 0; }
static int mmc_clock_opt_set(void *data, u64 val) { struct mmc_host *host = data; /* We need this check due to input value is u64 */ if (val > host->f_max) return -EINVAL; mmc_claim_host(host); mmc_set_clock(host, (unsigned int) val); mmc_release_host(host); return 0; }
static int mmc_clock_setting_store(struct device *dev, struct device_attribute *attr, const char * buf, size_t count) { struct sdhci_msm_host *sdhci_mmc = mmc_control_mmchost; struct mmc_host *mmc = sdhci_mmc->mmc; if(mmc ==NULL) return -22; printk("%s : test mmc_clock_setting_store count=%d .\n", __func__,count); memcpy(received_set_value, buf, count); if(count ==2) { clock_setting_value = ((received_set_value[0]-0x30) *10); clock_setting_value += (received_set_value[1]-0x30) ; } else if (count == 3) { clock_setting_value = ((received_set_value[0]-0x30) *100); clock_setting_value += ((received_set_value[1]-0x30) *10); clock_setting_value += (received_set_value[2]-0x30) ; } else { printk("%s : input data failed !!!\n", __func__); return -22; } clock_setting_value = (clock_setting_value * 1000 * 1000); mmc_host_clk_hold(mmc); mmc_set_clock(mmc, clock_setting_value); mmc_host_clk_release(mmc); clock_max = clock_setting_value; clock_flag = 1; clock_show = clock_setting_value; printk("%s : result of clock value =%d\n", __func__,clock_setting_value); return count; }
static int mmc_clock_opt_set(void *data, u64 val) { struct mmc_host *host = data; if (val > host->f_max) return -EINVAL; mmc_rpm_hold(host, &host->class_dev); mmc_claim_host(host); mmc_set_clock(host, (unsigned int) val); mmc_release_host(host); mmc_rpm_release(host, &host->class_dev); return 0; }
static int meson_mmc_probe(struct udevice *dev) { struct meson_mmc_platdata *pdata = dev_get_platdata(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct mmc *mmc = &pdata->mmc; struct mmc_config *cfg = &pdata->cfg; uint32_t val; cfg->voltages = MMC_VDD_33_34 | MMC_VDD_32_33 | MMC_VDD_31_32 | MMC_VDD_165_195; cfg->host_caps = MMC_MODE_8BIT | MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS; cfg->f_min = DIV_ROUND_UP(SD_EMMC_CLKSRC_24M, CLK_MAX_DIV); cfg->f_max = 100000000; /* 100 MHz */ cfg->b_max = 511; /* max 512 - 1 blocks */ cfg->name = dev->name; mmc->priv = pdata; upriv->mmc = mmc; mmc_set_clock(mmc, cfg->f_min, MMC_CLK_ENABLE); /* reset all status bits */ meson_write(mmc, STATUS_MASK, MESON_SD_EMMC_STATUS); /* disable interrupts */ meson_write(mmc, 0, MESON_SD_EMMC_IRQ_EN); /* enable auto clock mode */ val = meson_read(mmc, MESON_SD_EMMC_CFG); val &= ~CFG_SDCLK_ALWAYS_ON; val |= CFG_AUTO_CLK; meson_write(mmc, val, MESON_SD_EMMC_CFG); return 0; }
/* * Starting point for MMC card init. */ int mmc_attach_mmc(struct mmc_host *host, u32 ocr) { struct mmc_card *card; int err; u32 cid[4]; unsigned int max_dtr; BUG_ON(!host); BUG_ON(!host->claimed); mmc_attach_bus(host, &mmc_ops); host->ocr = mmc_select_voltage(host, ocr); /* * Can we support the voltage of the card? */ if (!host->ocr) goto err; /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ mmc_send_op_cond(host, host->ocr | (1 << 30), NULL); /* * Fetch CID from card. */ err = mmc_all_send_cid(host, cid); if (err != MMC_ERR_NONE) goto err; /* * Allocate card structure. */ card = mmc_alloc_card(host); if (IS_ERR(card)) goto err; card->type = MMC_TYPE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); /* * Set card RCA. */ err = mmc_set_relative_addr(card); if (err != MMC_ERR_NONE) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err != MMC_ERR_NONE) goto free_card; mmc_decode_csd(card); mmc_decode_cid(card); /* * Fetch and process extened CSD. * This will switch into high-speed and wide bus modes, * as available. */ err = mmc_select_card(card); if (err != MMC_ERR_NONE) goto free_card; err = mmc_process_ext_csd(card); if (err != MMC_ERR_NONE) goto free_card; /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); host->card = card; mmc_release_host(host); err = mmc_register_card(card); if (err) goto reclaim_host; return 0; reclaim_host: mmc_claim_host(host); free_card: mmc_remove_card(card); host->card = NULL; err: mmc_detach_bus(host); mmc_release_host(host); return 0; }
/* * Handle the detection and initialisation of a card. * * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err; u32 cid[4]; unsigned int max_dtr; BUG_ON(!host); WARN_ON(!host->claimed); /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ #if !defined(CONFIG_PLAT_BCM476X) // @KP: 090306 err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); #else err = mmc_send_op_cond(host, ocr | (1 << 30), &(host->ocr)); #endif if (err) goto err; /* * For SPI, enable CRC as appropriate. */ if (mmc_host_is_spi(host)) { err = mmc_spi_set_crc(host, use_spi_crc); if (err) goto err; } /* * Fetch CID from card. */ if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else err = mmc_all_send_cid(host, cid); if (err) goto err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { err = -ENOENT; goto err; } card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host, &mmc_type); if (IS_ERR(card)) { err = PTR_ERR(card); goto err; } card->type = MMC_TYPE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); } /* * For native busses: set card RCA and quit open drain mode. */ if (!mmc_host_is_spi(host)) { err = mmc_set_relative_addr(card); if (err) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err) goto free_card; err = mmc_decode_csd(card); if (err) goto free_card; err = mmc_decode_cid(card); if (err) goto free_card; } /* * Select card, as all following commands rely on that. */ if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto free_card; } if (!oldcard) { /* * Fetch and process extended CSD. */ err = mmc_read_ext_csd(card); if (err) goto free_card; } /* * Activate wide bus (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { unsigned ext_csd_bit, bus_width; if (host->caps & MMC_CAP_8_BIT_DATA) { ext_csd_bit = EXT_CSD_BUS_WIDTH_8; bus_width = MMC_BUS_WIDTH_8; printk(KERN_INFO "%s: mmc_init_card: Switching to 8-bit bus width\n", mmc_hostname(card->host)); } else { ext_csd_bit = EXT_CSD_BUS_WIDTH_4; bus_width = MMC_BUS_WIDTH_4; } err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bit); if (err) goto free_card; mmc_set_bus_width(card->host, bus_width); } /* * Activate high speed (if supported) */ if ((card->ext_csd.hs_max_dtr != 0) && #ifdef CONFIG_MMC_BCM_SD (host->f_max > SDHCI_HOST_MAX_CLK_LS_MODE) && #endif (host->caps & MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); if (err) goto free_card; mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } #if (defined(CONFIG_ARCH_FPGA11107)) max_dtr >>= 5; /* Divide clock by 32 for FPGA scale factor */ #endif mmc_set_clock(host, max_dtr); if (!oldcard) host->card = card; return 0; free_card: if (!oldcard) mmc_remove_card(card); err: return err; }
static int mmc_awake(struct mmc_host *host) { struct mmc_card *card = host->card; int err = -ENOSYS; int ddr = 0; unsigned int max_dtr; if (card && card->ext_csd.rev >= 3) { err = mmc_card_sleepawake(host, 0); if (err < 0) { pr_debug("%s: Error %d while awaking sleeping card", mmc_hostname(host), err); return err; } /* * Ensure eMMC user default partition is enabled */ if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) { card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG, card->ext_csd.part_config, card->ext_csd.part_time); if (err && err != -EBADMSG) goto err; } /* * Activate high speed (if supported) */ if ((card->ext_csd.hs_max_dtr != 0) && (host->caps & MMC_CAP_MMC_HIGHSPEED)) { mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); /* * Indicate DDR mode (if supported). */ if (mmc_card_highspeed(card)) { if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) && ((host->caps & (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50)) == (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50))) ddr = MMC_1_8V_DDR_MODE; else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) && ((host->caps & (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50)) == (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50))) ddr = MMC_1_2V_DDR_MODE; } /* * Activate wide bus and DDR (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { static unsigned ext_csd_bits[][2] = { { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 }, { EXT_CSD_BUS_WIDTH_4, EXT_CSD_DDR_BUS_WIDTH_4 }, { EXT_CSD_BUS_WIDTH_1, EXT_CSD_BUS_WIDTH_1 }, }; static unsigned bus_widths[] = { MMC_BUS_WIDTH_8, MMC_BUS_WIDTH_4, MMC_BUS_WIDTH_1 }; unsigned idx, bus_width = 0; if (host->caps & MMC_CAP_8_BIT_DATA) idx = 0; else idx = 1; for (; idx < ARRAY_SIZE(bus_widths); idx++) { bus_width = bus_widths[idx]; if (bus_width == MMC_BUS_WIDTH_1) ddr = 0; /* no DDR for 1-bit width */ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][0], 0); if (!err) { mmc_set_bus_width(card->host, bus_width); break; } } if (!err && ddr) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][1], 0); } if (err) { printk(KERN_WARNING "%s: switch to bus width %d ddr %d " "failed\n", mmc_hostname(card->host), 1 << bus_width, ddr); goto err; } else if (ddr) { /* * eMMC cards can support 3.3V to 1.2V i/o (vccq) * signaling. * * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. * * 1.8V vccq at 3.3V core voltage (vcc) is not required * in the JEDEC spec for DDR. * * Do not force change in vccq since we are obviously * working and no change to vccq is needed. * * WARNING: eMMC rules are NOT the same as SD DDR */ if (ddr == MMC_1_2V_DDR_MODE) { err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0); if (err) goto err; } mmc_card_set_ddr_mode(card); mmc_set_timing(card->host, MMC_TIMING_UHS_DDR50); mmc_set_bus_width(card->host, bus_width); } } } err: return err; }
/* * Handle the detection and initialisation of a card. * * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err, ddr = 0; u32 cid[4]; unsigned int max_dtr; u32 rocr; u8 *ext_csd = NULL; #if defined(CONFIG_MMC_DISABLE_WP_RFG_5) /* 2012 March detect write protection status for SHR/SHR#K workaround */ /* mfg partition start sector = LBA 65536 */ unsigned char WP_STATUS[8] = {0}; #endif BUG_ON(!host); WARN_ON(!host->claimed); /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr); if (err) goto err; /* * For SPI, enable CRC as appropriate. */ if (mmc_host_is_spi(host)) { err = mmc_spi_set_crc(host, use_spi_crc); if (err) goto err; } /* * Fetch CID from card. */ if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else err = mmc_all_send_cid(host, cid); if (err) goto err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { err = -ENOENT; goto err; } card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host, &mmc_type); if (IS_ERR(card)) { err = PTR_ERR(card); goto err; } card->type = MMC_TYPE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); } /* * For native busses: set card RCA and quit open drain mode. */ if (!mmc_host_is_spi(host)) { err = mmc_set_relative_addr(card); if (err) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err) goto free_card; err = mmc_decode_csd(card); if (err) goto free_card; err = mmc_decode_cid(card); if (err) goto free_card; } /* * Select card, as all following commands rely on that. */ if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto free_card; } if (!oldcard) { /* * Fetch and process extended CSD. */ err = mmc_get_ext_csd(card, &ext_csd); if (err) goto free_card; err = mmc_read_ext_csd(card, ext_csd); if (err) goto free_card; /* If doing byte addressing, check if required to do sector * addressing. Handle the case of <2GB cards needing sector * addressing. See section 8.1 JEDEC Standard JED84-A441; * ocr register has bit 30 set for sector addressing. */ if (!(mmc_card_blockaddr(card)) && (rocr & (1<<30))) mmc_card_set_blockaddr(card); /* Erase size depends on CSD and Extended CSD */ mmc_set_erase_size(card); if (card->ext_csd.sectors && (rocr & MMC_CARD_SECTOR_ADDR)) mmc_card_set_blockaddr(card); } /* If enhanced_area_en is TRUE, host needs to enable ERASE_GRP_DEF */ /* bit. This bit will be lost every time after a reset or power off. */ /* For 2GB eMMC, there will no HC_ERASE_GROUP define */ if (card->ext_csd.sectors > 4194304) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_ERASE_GROUP_DEF, 1, 0); if (err && err != -EBADMSG) goto free_card; if (err) { err = 0; /* * Just disable enhanced area off & sz * will try to enable ERASE_GROUP_DEF * during next time reinit */ card->ext_csd.enhanced_area_offset = -EINVAL; card->ext_csd.enhanced_area_size = -EINVAL; } else { card->ext_csd.erase_group_def = 1; /* * enable ERASE_GRP_DEF successfully. * This will affect the erase size, so * here need to reset erase size */ mmc_set_erase_size(card); } } /* * Ensure eMMC user default partition is enabled */ if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) { card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG, card->ext_csd.part_config, card->ext_csd.part_time); if (err && err != -EBADMSG) goto free_card; } /* For SanDisk X3, we have to enable power class 4 */ if (card->cid.manfid == 0x45) { if (card->ext_csd.sectors > 33554432) { /* the storage size larger than 16GB */ err = mmc_switch(card, EXT_CSD_CMD_SET_ZERO, EXT_CSD_POWER_CLASS, 4, 0); if (err && err != -EBADMSG) goto free_card; if (err) { printk(KERN_WARNING "%s: switch to power class 4 failed\n", mmc_hostname(card->host)); err = 0; } else { printk(KERN_WARNING "%s: switch to power class 4 sucessfully\n", mmc_hostname(card->host)); } } else if (card->ext_csd.sectors == 31105024) { err = mmc_switch(card, EXT_CSD_CMD_SET_ZERO, EXT_CSD_POWER_CLASS, 4, 0); if (err && err != -EBADMSG) goto free_card; if (err) { printk(KERN_WARNING "%s: switch to power class 4 failed\n", mmc_hostname(card->host)); err = 0; } else { printk(KERN_WARNING "%s: switch to power class 4 sucessfully\n", mmc_hostname(card->host)); } } } /* * Activate high speed (if supported) */ if ((card->ext_csd.hs_max_dtr != 0) && (host->caps & MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1, 0); if (err && err != -EBADMSG) goto free_card; if (err) { printk(KERN_WARNING "%s: switch to highspeed failed\n", mmc_hostname(card->host)); err = 0; } else { mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } } if (card->cid.manfid == 0x45) { /* Sandisk 24nm extreme 16G */ if ((card->ext_csd.sectors == 31105024) && !strcmp(card->cid.prod_name, "SEM16G")) card->wr_perf = 12; /* Sandisk 24nm extreme 32G */ else if ((card->ext_csd.sectors == 62324736) && !strcmp(card->cid.prod_name, "SEM32G")) card->wr_perf = 12; } else if (card->cid.manfid == 0x15) { pr_info("%s: sectors %u\n", mmc_hostname(card->host), card->ext_csd.sectors); /* Samsung 27nm 16G */ if ((card->ext_csd.sectors == 30777344) && !strcmp(card->cid.prod_name, "KYL00M")) card->wr_perf = 11; else if ((card->ext_csd.sectors == 62521344) && !strcmp(card->cid.prod_name, "MBG8FA")) card->wr_perf = 11; /* Samsung 21nm 16G */ else if ((card->ext_csd.sectors == 30535680) && !strcmp(card->cid.prod_name, "MAG2GA")) card->wr_perf = 14; } /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); /* * Indicate DDR mode (if supported). */ if (mmc_card_highspeed(card)) { if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) && ((host->caps & (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50)) == (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50))) ddr = MMC_1_8V_DDR_MODE; else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) && ((host->caps & (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50)) == (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50))) ddr = MMC_1_2V_DDR_MODE; } /* * Activate wide bus and DDR (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { static unsigned ext_csd_bits[][2] = { { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 }, { EXT_CSD_BUS_WIDTH_4, EXT_CSD_DDR_BUS_WIDTH_4 }, { EXT_CSD_BUS_WIDTH_1, EXT_CSD_BUS_WIDTH_1 }, }; static unsigned bus_widths[] = { MMC_BUS_WIDTH_8, MMC_BUS_WIDTH_4, MMC_BUS_WIDTH_1 }; unsigned idx, bus_width = 0; if (host->caps & MMC_CAP_8_BIT_DATA) idx = 0; else idx = 1; for (; idx < ARRAY_SIZE(bus_widths); idx++) { bus_width = bus_widths[idx]; if (bus_width == MMC_BUS_WIDTH_1) ddr = 0; /* no DDR for 1-bit width */ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][0], 0); if (!err) { mmc_set_bus_width(card->host, bus_width); /* * If controller can't handle bus width test, * compare ext_csd previously read in 1 bit mode * against ext_csd at new bus width */ if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) err = mmc_compare_ext_csds(card, bus_width); else err = mmc_bus_test(card, bus_width); if (!err) break; } } if (!err && ddr) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][1], 0); } if (err) { printk(KERN_WARNING "%s: switch to bus width %d ddr %d " "failed\n", mmc_hostname(card->host), 1 << bus_width, ddr); goto free_card; } else if (ddr) { /* * eMMC cards can support 3.3V to 1.2V i/o (vccq) * signaling. * * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. * * 1.8V vccq at 3.3V core voltage (vcc) is not required * in the JEDEC spec for DDR. * * Do not force change in vccq since we are obviously * working and no change to vccq is needed. * * WARNING: eMMC rules are NOT the same as SD DDR */ if (ddr == MMC_1_2V_DDR_MODE) { err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0); if (err) goto err; } mmc_card_set_ddr_mode(card); mmc_set_timing(card->host, MMC_TIMING_UHS_DDR50); mmc_set_bus_width(card->host, bus_width); } } #if defined(CONFIG_MMC_DISABLE_WP_RFG_5) /* 2012 March detect write protection status for SHR/SHR#K workaround */ /* mfg partition start sector = LBA 65536 */ err = mmc_set_block_length(card, 8); if (err && err != -EBADMSG) goto free_card; if (err) { pr_err("%s: set block length to 8 fail\n", mmc_hostname(card->host)); err = 0; } err = mmc_send_write_prot_type(card, WP_STATUS, 65536); if (err && err != -EBADMSG) goto free_card; if (err) { pr_err("%s: send write protection type at address 65536 failed\n", mmc_hostname(card->host)); err = 0; } if (WP_STATUS[0] & 0xAA) { pr_info("%s: trigger software write protection\n", mmc_hostname(card->host)); card->write_prot_type = 1; } else { pr_info("%s: disable software write protection\n", mmc_hostname(card->host)); card->write_prot_type = 0; } err = mmc_set_block_length(card, 512); if (err && err != -EBADMSG) goto free_card; if (err) { pr_err("%s: set block length to 512 fail\n", mmc_hostname(card->host)); err = 0; } #endif #if defined(CONFIG_ARCH_MSM7230) /* 2012 March detect write protection status for Kingston workaround System partition start sector = LBA 200704 */ if (card->cid.manfid == 0x70) { unsigned char WP_STATUS[8] = {0}; err = mmc_set_block_length(card, 8); if (err && err != -EBADMSG) goto free_card; if (err) { pr_err("%s: set block length to 8 fail\n", mmc_hostname(card->host)); err = 0; } err = mmc_send_write_prot_type(card, WP_STATUS, 200704); if (err && err != -EBADMSG) goto free_card; if (err) { pr_err("%s: send write protection type at address 200704 failed\n", mmc_hostname(card->host)); err = 0; } if (WP_STATUS[0] & 0xAA) { pr_info("%s: trigger Kingston write protection\n", mmc_hostname(card->host)); card->write_prot_type = 1; } else { pr_info("%s: disable Kingston write protection\n", mmc_hostname(card->host)); card->write_prot_type = 0; } err = mmc_set_block_length(card, 512); if (err && err != -EBADMSG) goto free_card; if (err) { pr_err("%s: set block length to 512 fail\n", mmc_hostname(card->host)); err = 0; } } #endif if (!oldcard) host->card = card; mmc_free_ext_csd(ext_csd); return 0; free_card: if (!oldcard) mmc_remove_card(card); err: mmc_free_ext_csd(ext_csd); return err; }
static int autok_writeproc(struct file *file,const char *buffer, unsigned long count, void *data) { //int err = 0; //char *envp[2]; char stage; char bufferContent[PROC_BUF_SIZE]; char *bufContIdx; //char sdiofunc_addr[11]; //char autok_stage1_result[256]; struct msdc_host *host; struct sdio_func *sdioFunc; struct mmc_host *mmc; int len; int procParamsOffset = 0; int i; printk(KERN_INFO "[%s] (/proc/%s) called\n", __func__, PROC_AUTOK_NAME); if(count >= PROC_BUF_SIZE) { printk(KERN_INFO "[%s] proc input size (%ld) is larger than buffer size (%d) \n", __func__, count, PROC_BUF_SIZE); return -EFAULT; } if (copy_from_user(bufferContent, buffer, count)) return -EFAULT; bufferContent[count] = '\0'; printk(KERN_INFO "[%s] bufferContent: (count = %ld)\n", __func__, count); for(i = 0; i < count; i++) printk(" %x ", (unsigned int)bufferContent[i]); printk("\n"); // Parsing bufferContent bufContIdx = bufferContent; sdioFunc = (struct sdio_func *)(*(int *)bufContIdx); bufContIdx += 4; procParamsOffset += 4; stage = *bufContIdx; bufContIdx += 1; procParamsOffset += 1; if(count <= procParamsOffset) { stage = 1; } else { memcpy(&len, bufContIdx, sizeof(int)); bufContIdx = bufContIdx + sizeof(int); procParamsOffset += sizeof(int); if(len > count - procParamsOffset) { printk(KERN_INFO "[%s] autok stage 1 result len (%d) is larger than actual proc input size (%ld) \n", __func__, len, count - procParamsOffset); return -EFAULT; } memcpy(g_autok_thread_data.autok_stage1_result, bufContIdx, len); g_autok_thread_data.len = len; printk(KERN_INFO "[%s] autok_stage1_result: (len = %d)\n", __func__, len); for(i = 0; i < len; i++) printk(" %x ", (unsigned int)g_autok_thread_data.autok_stage1_result[i]); printk("\n"); } printk(KERN_INFO "[%s] stage = %d\n", __func__, stage); if(sdioFunc == NULL) { printk(KERN_INFO "[%s] sdioFunc = NULL\n", __func__); return -EFAULT; } mmc = sdioFunc->card->host; host = mmc_priv(mmc); // Set clock to card max clock sdio_autok_processed = 1; printk(KERN_INFO "[%s] mmc->ios.clock = %d, mmc->ios.power_mode = %d\n", __func__, mmc->ios.clock, mmc->ios.power_mode); mmc_set_clock(mmc, mmc->ios.clock); g_autok_thread_data.host = host; g_autok_thread_data.stage = stage; #ifdef USE_KERNEL_THREAD task = kthread_run(&autok_thread_func,(void *)(&g_autok_thread_data),"autokp"); //if(!IS_ERR(task)) // wake_up_process(task); #else // USE_KERNEL_THREAD queue_delayed_work_on(0, g_autok_wq, (struct delayed_work *)&g_autok_thread_data, msecs_to_jiffies(0)); #endif // USE_KERNEL_THREAD return count; }
static int autok_thread_func(void *data) { struct sdio_autok_thread_data *autok_thread_data; struct sched_param param = { .sched_priority = 99 }; unsigned int vcore_uv = 0; struct msdc_host *host; struct mmc_host *mmc; char stage = 0; int i,j; int res = 0; int doStg2 = 0; void __iomem *base; u32 dma; struct timeval t0,t1; int time_in_s, time_in_ms; // unsigned long flags; autok_thread_data = (struct sdio_autok_thread_data *)data; sched_setscheduler(current, SCHED_FIFO, ¶m); // preempt_disable(); host = autok_thread_data->host; mmc = host->mmc; stage = autok_thread_data->stage; base = host->base; dma = msdc_dma_status(); // Inform msdc_set_mclk() auto-K is going to process sdio_autok_processed = 1; // Set clock to card max clock mmc_set_clock(mmc, mmc->ios.clock); msdc_sdio_set_long_timing_delay_by_freq(host, mmc->ios.clock); msdc_ungate_clock(host); // Set PIO mode msdc_dma_off(); vcore_uv = autok_get_current_vcore_offset(); // End of initialize do_gettimeofday(&t0); if(autok_thread_data->log != NULL) log_info = autok_thread_data->log; if(stage == 1) { // call stage 1 auto-K callback function autok_thread_data->is_autok_done[host->id] = 0; res = msdc_autok_stg1_cal(host, vcore_uv, autok_thread_data->p_autok_predata); if(res){ printk(KERN_INFO "[%s] Auto-K stage 1 fail, res = %d, set msdc parameter settings stored in nvram to 0\n", __func__, res); memset(autok_thread_data->p_autok_predata->ai_data[0], 0, autok_thread_data->p_autok_predata->param_count * sizeof(unsigned int)); autok_thread_data->is_autok_done[host->id] = 2; } } else if(stage == 2) { // call stage 2 auto-K callback function // check if msdc params of different volt are all 0, if so, that means auto-K stg1 failed for(i=0; i<autok_thread_data->p_autok_predata->vol_count; i++){ for(j=0; j<autok_thread_data->p_autok_predata->param_count; j++){ if(autok_thread_data->p_autok_predata->ai_data[i][j].data.sel != 0){ doStg2 = 1; break; } } if(doStg2) break; } if(doStg2){ res = msdc_autok_stg2_cal(host, autok_thread_data->p_autok_predata, vcore_uv); if(res){ printk(KERN_INFO "[%s] Auto-K stage 2 fail, res = %d, downgrade SDIO freq to 50MHz\n", __func__, res); mmc->ios.clock = 50*1000*1000; mmc_set_clock(mmc, mmc->ios.clock); msdc_sdio_set_long_timing_delay_by_freq(host, mmc->ios.clock); sdio_autok_processed = 0; for (i = 0; i < HOST_MAX_NUM; i++) { if (autok_thread_data->p_autok_progress[i].host_id == -1) { break; } else if (autok_thread_data->p_autok_progress[i].host_id == host->id) { autok_thread_data->p_autok_progress[i].fail = 1; } } } } else { // Auto-K stg1 failed printk(KERN_INFO "[%s] Auto-K stage 1 fail, downgrade SDIO freq to 50MHz\n", __func__); mmc->ios.clock = 50*1000*1000; mmc_set_clock(mmc, mmc->ios.clock); msdc_sdio_set_long_timing_delay_by_freq(host, mmc->ios.clock); sdio_autok_processed = 0; for (i = 0; i < HOST_MAX_NUM; i++) { if (autok_thread_data->p_autok_progress[i].host_id == -1) { break; } else if (autok_thread_data->p_autok_progress[i].host_id == host->id) { autok_thread_data->p_autok_progress[i].fail = 1; } } } log_info = NULL; } else { printk(KERN_INFO "[%s] stage %d doesn't support in auto-K\n", __func__, stage); //return -EFAULT; } do_gettimeofday(&t1); if(dma == DMA_ON) msdc_dma_on(); msdc_gate_clock(host,1); // [FIXDONE] Tell native module that auto-K has finished if(stage == 1) autok_calibration_done(host->id, autok_thread_data); else if(stage == 2){ for(i=0; i<HOST_MAX_NUM; i++){ if(autok_thread_data->p_autok_progress[i].host_id == -1){ break; } else if(autok_thread_data->p_autok_progress[i].host_id == host->id){ autok_thread_data->p_autok_progress[i].done = 1; if(autok_thread_data->p_autok_progress[i].done > 0) complete(&autok_thread_data->autok_completion[i]); } } } time_in_s = (t1.tv_sec - t0.tv_sec); time_in_ms = (t1.tv_usec - t0.tv_usec)>>10; printk(KERN_ERR "\n[AUTOKK][Stage%d] Timediff is %d.%d(s)\n", (int)stage, time_in_s, time_in_ms ); // preempt_enable(); return 0; } #endif int send_autok_uevent(char *text, struct msdc_host *host) { int err = 0; char *envp[3]; char *host_buf; char *what_buf; //struct msdc_host *host = mtk_msdc_host[id]; host_buf = kzalloc(sizeof(char)*128, GFP_KERNEL); what_buf = kzalloc(sizeof(char)*128, GFP_KERNEL); snprintf(host_buf, MAX_ARGS_BUF-1, "HOST=%d", host->id); snprintf(what_buf, MAX_ARGS_BUF-1, "WHAT=%s", text); envp[0] = host_buf; envp[1] = what_buf; envp[2] = NULL; if(host != NULL){ err = kobject_uevent_env(&host->mmc->class_dev.kobj, KOBJ_CHANGE, envp); } kfree(host_buf); kfree(what_buf); if(err < 0) printk(KERN_INFO "[%s] kobject_uevent_env error = %d\n", __func__, err); return err; }
/* * Handle the detection and initialisation of a card. * * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err; u32 cid[4]; #if defined(CONFIG_INAND_VERSION_PATCH) u32 rocr[1]; #endif unsigned int max_dtr; BUG_ON(!host); WARN_ON(!host->claimed); /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ #if defined(CONFIG_INAND_VERSION_PATCH) err = mmc_send_op_cond(host, ocr | (1 << 30), rocr); #else err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); #endif if (err) goto err; /* * For SPI, enable CRC as appropriate. */ if (mmc_host_is_spi(host)) { err = mmc_spi_set_crc(host, use_spi_crc); if (err) goto err; } /* * Fetch CID from card. */ if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else err = mmc_all_send_cid(host, cid); if (err) goto err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { err = -ENOENT; goto err; } card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host, &mmc_type); if (IS_ERR(card)) { err = PTR_ERR(card); goto err; } card->type = MMC_TYPE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); host->card = card; } /* * For native busses: set card RCA and quit open drain mode. */ if (!mmc_host_is_spi(host)) { err = mmc_set_relative_addr(card); if (err) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err) goto free_card; err = mmc_decode_csd(card); if (err) goto free_card; err = mmc_decode_cid(card); if (err) goto free_card; } /* * Select card, as all following commands rely on that. */ if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto free_card; } if (!oldcard) { /* * Fetch and process extended CSD. */ err = mmc_read_ext_csd(card); if (err) goto free_card; #if defined(CONFIG_INAND_VERSION_PATCH) if (rocr[0] & 0x40000000) mmc_card_set_blockaddr(card); #endif //[NAGSM_Android_HDLNC_SDcard_SEOJW_2011_01_12 : eMMC Trim add #if defined (CONFIG_MMC_DISCARD) && defined (CONFIG_S5PC110_DEMPSEY_BOARD) mmc_set_erase_size(card); #endif /* CONFIG_MMC_DISCARD */ } /* * Activate high speed (if supported) */ if ((card->ext_csd.hs_max_dtr != 0) && (host->caps & MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); if (err && err != -EBADMSG) goto free_card; if (err) { printk(KERN_WARNING "%s: switch to highspeed failed\n", mmc_hostname(card->host)); err = 0; } else { mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } } /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); /* * Activate wide bus (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { unsigned ext_csd_bit, bus_width; if (host->caps & MMC_CAP_8_BIT_DATA) { ext_csd_bit = EXT_CSD_BUS_WIDTH_8; bus_width = MMC_BUS_WIDTH_8; } else { ext_csd_bit = EXT_CSD_BUS_WIDTH_4; bus_width = MMC_BUS_WIDTH_4; } err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bit); if (err && err != -EBADMSG) goto free_card; if (err) { printk(KERN_WARNING "%s: switch to bus width %d " "failed\n", mmc_hostname(card->host), 1 << bus_width); err = 0; } else { mmc_set_bus_width(card->host, bus_width); printk(KERN_WARNING "%s: switch to bus width %d " , mmc_hostname(card->host), 1 << bus_width); } } return 0; free_card: if (!oldcard) { mmc_remove_card(card); host->card = NULL; } err: return err; }
static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err; u32 cid[4]; unsigned int max_dtr; #ifdef CONFIG_MMC_PARANOID_SD_INIT int retries; #endif BUG_ON(!host); WARN_ON(!host->claimed); mmc_go_idle(host); err = mmc_send_if_cond(host, ocr); if (!err) ocr |= 1 << 30; err = mmc_send_app_op_cond(host, ocr, NULL); if (err) goto err; if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else err = mmc_all_send_cid(host, cid); if (err) goto err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { err = -ENOENT; goto err; } card = oldcard; } else { card = mmc_alloc_card(host, &sd_type); if (IS_ERR(card)) { err = PTR_ERR(card); goto err; } card->type = MMC_TYPE_SD; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); } if (!mmc_host_is_spi(host)) { err = mmc_send_relative_addr(host, &card->rca); if (err) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } if (!oldcard) { err = mmc_send_csd(card, card->raw_csd); if (err) goto free_card; err = mmc_decode_csd(card); if (err) goto free_card; mmc_decode_cid(card); } if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto free_card; } if (!oldcard) { err = mmc_app_send_scr(card, card->raw_scr); if (err) goto free_card; err = mmc_decode_scr(card); if (err < 0) goto free_card; #ifdef CONFIG_MMC_PARANOID_SD_INIT for (retries = 1; retries <= 3; retries++) { err = mmc_read_switch(card); if (!err) { if (retries > 1) { printk(KERN_WARNING "%s: recovered\n", mmc_hostname(host)); } break; } else { printk(KERN_WARNING "%s: read switch failed (attempt %d)\n", mmc_hostname(host), retries); } } #else err = mmc_read_switch(card); #endif if (err) goto free_card; } if (mmc_host_is_spi(host)) { err = mmc_spi_set_crc(host, use_spi_crc); if (err) goto free_card; } err = mmc_switch_hs(card); if (err) goto free_card; max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->sw_caps.hs_max_dtr) max_dtr = card->sw_caps.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); if ((host->caps & MMC_CAP_4_BIT_DATA) && (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); if (err) goto free_card; mmc_set_bus_width(host, MMC_BUS_WIDTH_4); } if (!oldcard) { if (!host->ops->get_ro || host->ops->get_ro(host) < 0) { printk(KERN_WARNING "%s: host does not " "support reading read-only " "switch. assuming write-enable.\n", mmc_hostname(host)); } else { if (host->ops->get_ro(host) > 0) mmc_card_set_readonly(card); } } if (!oldcard) host->card = card; return 0; free_card: if (!oldcard) mmc_remove_card(card); err: return err; }
/* * Handle the detection and initialisation of a card. * * In the case of a resume, "curcard" will contain the card * we're trying to reinitialise. */ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err; u32 cid[4]; unsigned int max_dtr; BUG_ON(!host); WARN_ON(!host->claimed); /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); if (err) goto err; /* * For SPI, enable CRC as appropriate. */ if (mmc_host_is_spi(host)) { err = mmc_spi_set_crc(host, use_spi_crc); if (err) goto err; } /* * Fetch CID from card. */ if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else err = mmc_all_send_cid(host, cid); if (err) goto err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { err = -ENOENT; goto err; } card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host); if (IS_ERR(card)) { err = PTR_ERR(card); goto err; } card->type = MMC_TYPE_MMC; host->mode = MMC_MODE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); } /* * For native busses: set card RCA and quit open drain mode. */ if (!mmc_host_is_spi(host)) { err = mmc_set_relative_addr(card); if (err) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err) goto free_card; err = mmc_decode_csd(card); if (err) goto free_card; err = mmc_decode_cid(card); if (err) goto free_card; } /* * Select card, as all following commands rely on that. */ if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto free_card; } if (!oldcard) { /* * Fetch and process extended CSD. */ err = mmc_read_ext_csd(card); if (err) goto free_card; } /* * Activate high speed (if supported) */ if ((card->ext_csd.hs_max_dtr != 0) && (host->caps & MMC_CAP_MMC_HIGHSPEED)) { err = mmc_execute_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); if (err) goto free_card; mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); /* * HACK: some devices, Hynix flash in particular, seem * to need a little pause here or it wont respond to any * further commands. */ // msleep(10); mdelay(10); /* * Activate wide bus (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & MMC_CAP_8_BIT_DATA)) { err = mmc_execute_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8); if (err) goto free_card; mmc_set_bus_width(card->host, MMC_BUS_WIDTH_8); } else if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & MMC_CAP_4_BIT_DATA)) { err = mmc_execute_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); if (err) goto free_card; mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); } if (!oldcard) host->card = card; return 0; free_card: if (!oldcard) mmc_remove_card(card); err: return err; }
static int mmc_set_bus_speed_mode(struct mmc_card *card, u32 speed) { int err = 0; u32 clock = 0; u32 bus_width = 0; u8 card_type = card->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_MASK; u32 caps = card->host->caps, caps2 = card->host->caps2; /* HS_TIMING is set to 2 in HS200 and all other modes needs to be 1 */ if (speed == UHS_DDR50_BUS_SPEED) { /* check card and host capability for DDR50 to proceed */ if (!(((caps & MMC_CAP_1_8V_DDR) && (card_type & EXT_CSD_CARD_TYPE_DDR_1_8V)) || ((caps & MMC_CAP_1_2V_DDR) && (card_type & EXT_CSD_CARD_TYPE_DDR_1_2V)))) { err = -EINVAL; goto err_node; } err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1, 0); if (err) { pr_err("%s: switch to HS_TIMING failed with error %d\n", mmc_hostname(card->host), err); goto err_node; } else { if (card->host->caps & MMC_CAP_8_BIT_DATA) bus_width = EXT_CSD_DDR_BUS_WIDTH_8; else bus_width = EXT_CSD_DDR_BUS_WIDTH_4; err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, bus_width, card->ext_csd.generic_cmd6_time); if (err) { pr_err("%s: switch to bus width failed", mmc_hostname(card->host)); pr_err("with error %d\n", err); goto err_node; } clock = MMC_HIGH_DDR_MAX_DTR; } } else { /* check card and host capability for HS200 to proceed */ if (!(((caps2 & MMC_CAP2_HS200_1_8V_SDR) && (card_type & EXT_CSD_CARD_TYPE_SDR_1_8V)) || ((caps2 & MMC_CAP2_HS200_1_2V_SDR) && (card_type & EXT_CSD_CARD_TYPE_SDR_1_2V)))) { err = -EINVAL; goto err_node; } /* Based on host capability, set card side bus width */ if (card->host->caps & MMC_CAP_8_BIT_DATA) bus_width = EXT_CSD_BUS_WIDTH_8; else if (card->host->caps & MMC_CAP_4_BIT_DATA) bus_width = EXT_CSD_BUS_WIDTH_4; else bus_width = EXT_CSD_BUS_WIDTH_1; err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, bus_width, card->ext_csd.generic_cmd6_time); if (err) { pr_err("%s: switch to bus width failed with error %d\n", mmc_hostname(card->host), err); goto err_node; } err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 2, 0); if (err) { pr_err("%s: switch to HS_TIMING failed with error %d\n", mmc_hostname(card->host), err); goto err_node; } clock = MMC_HS200_MAX_DTR; } mmc_set_timing(card->host, card->host->ios.timing); if (card->host->ios.timing == MMC_TIMING_UHS_DDR50) { mmc_card_set_ddr_mode(card); card->state &= ~(MMC_STATE_HIGHSPEED_200 | MMC_STATE_HIGHSPEED_400 | MMC_STATE_HIGHSPEED); } else if (card->host->ios.timing == MMC_TIMING_MMC_HS200) { mmc_card_set_hs200(card); card->state &= ~(MMC_STATE_HIGHSPEED_DDR | MMC_STATE_HIGHSPEED_400 | MMC_STATE_HIGHSPEED); } /* Based on bus width selected for card, set host side bus width */ switch (bus_width) { case EXT_CSD_BUS_WIDTH_8: case EXT_CSD_DDR_BUS_WIDTH_8: mmc_set_bus_width(card->host, MMC_BUS_WIDTH_8); break; case EXT_CSD_BUS_WIDTH_4: case EXT_CSD_DDR_BUS_WIDTH_4: mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); break; default: mmc_set_bus_width(card->host, MMC_BUS_WIDTH_1); } mmc_set_clock(card->host, clock); err_node: 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; }
/* * Handle the detection and initialisation of a card. * * In the case of a resume, "curcard" will contain the card * we're trying to reinitialise. */ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err; u32 cid[4]; unsigned int max_dtr; unsigned int card_supports_8bit = 1; BUG_ON(!host); BUG_ON(!host->claimed); /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ err = mmc_send_op_cond(host, ocr | (1 << 30), &ocr); if (err != MMC_ERR_NONE) goto err; /* * Fetch CID from card. */ err = mmc_all_send_cid(host, cid); if (err != MMC_ERR_NONE) goto err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) goto err; card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host); if (IS_ERR(card)) goto err; card->type = MMC_TYPE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); printk(KERN_WARNING "[kwwo]%s: mmc-card detected\n", mmc_hostname(card->host)); } /* * Set card RCA. */ err = mmc_set_relative_addr(card); if (err != MMC_ERR_NONE) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err != MMC_ERR_NONE) goto free_card; err = mmc_decode_csd(card); if (err < 0) goto free_card; err = mmc_decode_cid(card); if (err < 0) goto free_card; } /* * Select card, as all following commands rely on that. */ err = mmc_select_card(card); if (err != MMC_ERR_NONE) goto free_card; if (!oldcard) { /* * Fetch and process extened CSD. */ err = mmc_read_ext_csd(card); if (err != MMC_ERR_NONE) goto free_card; } /* * Activate block addressing mode (if supported) */ if ( (ocr & (3 << 29)) == (2 << 29)) mmc_card_set_blockaddr(card); /* * Activate high speed (if supported) */ if ((card->ext_csd.hs_max_dtr != 0) && (host->caps & MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); if (err != MMC_ERR_NONE) goto free_card; mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; printk(KERN_INFO "[kwwo]%s: hs ext_csd.hs_max_dtr=%d\n", mmc_hostname(card->host), max_dtr); } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; printk(KERN_WARNING "[kwwo]%s: csd.max_dtr=%d\n", mmc_hostname(card->host), max_dtr); /* Limit 32nm MoviNAND MMC clock under 20MHz*/ if ( max_dtr > 20000000 ) { max_dtr = 20000000; printk(KERN_WARNING "MMC clk forced max. 20 MHz (16.5MHz)\n"); } } /* Workarounds for buggy cards */ if (card->cid.manfid == MMC_MANUFACTURER_SAMSUNG) { const int spare4bmaxspeed = 34700000; switch (card->cid.prv) { case 0x1b: case 0x16: if (max_dtr > spare4bmaxspeed) { /* reduce clock to below 34.7 MHz, 4 bit mode */ max_dtr = spare4bmaxspeed; card_supports_8bit = 0; printk(KERN_INFO "MMC: enabling workaround for movinand spare4b issue\n"); } break; } } mmc_set_clock(host, max_dtr); /* * Activate wide bus (if supported). */ if( card->csd.mmca_vsn >= CSD_SPEC_VER_4 ) { #ifdef CONFIG_MMC_8_BIT_TRANSFERS if ( (host->caps & MMC_CAP_8_BIT_DATA) && (card_supports_8bit) ) { err = mmc_switch( card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8 ); if( err != MMC_ERR_NONE ) goto free_card; mmc_set_bus_width( card->host, MMC_BUS_WIDTH_8 ); } else #endif if( host->caps & MMC_CAP_4_BIT_DATA ) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); if (err != MMC_ERR_NONE) goto free_card; mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); } } if (!oldcard) host->card = card; return MMC_ERR_NONE; free_card: if (!oldcard) mmc_remove_card(card); err: return MMC_ERR_FAILED; }
/* * Handle the detection and initialisation of a card. * * In the case of a resume, "curcard" will contain the card * we're trying to reinitialise. */ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err; u32 cid[4]; unsigned int max_dtr; BUG_ON(!host); BUG_ON(!host->claimed); /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); if (err != MMC_ERR_NONE) goto err; /* * Fetch CID from card. */ err = mmc_all_send_cid(host, cid); if (err != MMC_ERR_NONE) goto err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) goto err; card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host); if (IS_ERR(card)) goto err; card->type = MMC_TYPE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); } /* * Set card RCA. */ err = mmc_set_relative_addr(card); if (err != MMC_ERR_NONE) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err != MMC_ERR_NONE) goto free_card; err = mmc_decode_csd(card); if (err < 0) goto free_card; err = mmc_decode_cid(card); if (err < 0) goto free_card; } /* * Select card, as all following commands rely on that. */ err = mmc_select_card(card); if (err != MMC_ERR_NONE) goto free_card; if (!oldcard) { /* * Fetch and process extened CSD. */ err = mmc_read_ext_csd(card); if (err != MMC_ERR_NONE) goto free_card; } /* * Activate high speed (if supported) */ if ((card->ext_csd.hs_max_dtr != 0) && (host->caps & MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); if (err != MMC_ERR_NONE) goto free_card; mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); /* * Activate wide bus (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & MMC_CAP_4_BIT_DATA)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); if (err != MMC_ERR_NONE) goto free_card; mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); } if (!oldcard) host->card = card; return MMC_ERR_NONE; free_card: if (!oldcard) mmc_remove_card(card); err: return MMC_ERR_FAILED; }
/* * Handle the detection and initialisation of a card. * * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err; u32 cid[4]; BUG_ON(!host); WARN_ON(!host->claimed); err = mmc_sd_get_cid(host, ocr, cid); if (err) return err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) return -ENOENT; card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host, &sd_type); if (IS_ERR(card)) return PTR_ERR(card); card->type = MMC_TYPE_SD; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); } /* * For native busses: get card RCA and quit open drain mode. */ if (!mmc_host_is_spi(host)) { err = mmc_send_relative_addr(host, &card->rca); if (err) return err; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } if (!oldcard) { err = mmc_sd_get_csd(host, card); if (err) return err; mmc_decode_cid(card); } /* * Select card, as all following commands rely on that. */ if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) return err; } err = mmc_sd_setup_card(host, card, oldcard != NULL); if (err) goto free_card; /* * Attempt to change to high-speed (if supported) */ err = mmc_sd_switch_hs(card); if (err > 0) mmc_sd_go_highspeed(card); else if (err) goto free_card; /* * Set bus speed. */ mmc_set_clock(host, mmc_sd_get_max_clock(card)); /* * Switch to wider bus (if supported). */ if ((host->caps & MMC_CAP_4_BIT_DATA) && (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); if (err) goto free_card; mmc_set_bus_width(host, MMC_BUS_WIDTH_4); } host->card = card; return 0; free_card: if (!oldcard) mmc_remove_card(card); return err; }
/* * Handle the detection and initialisation of a card. * * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err, ddr = 0; u32 cid[4]; unsigned int max_dtr; u32 rocr; BUG_ON(!host); WARN_ON(!host->claimed); /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr); if (err) goto err; /* * For SPI, enable CRC as appropriate. */ if (mmc_host_is_spi(host)) { err = mmc_spi_set_crc(host, use_spi_crc); if (err) goto err; } /* * Fetch CID from card. */ if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else err = mmc_all_send_cid(host, cid); if (err) goto err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { err = -ENOENT; goto err; } card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host, &mmc_type); if (IS_ERR(card)) { err = PTR_ERR(card); goto err; } card->type = MMC_TYPE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); } /* * For native busses: set card RCA and quit open drain mode. */ if (!mmc_host_is_spi(host)) { err = mmc_set_relative_addr(card); if (err) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err) goto free_card; err = mmc_decode_csd(card); if (err) goto free_card; err = mmc_decode_cid(card); if (err) goto free_card; } /* * Select card, as all following commands rely on that. */ if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto free_card; } if (!oldcard) { /* * Fetch and process extended CSD. */ err = mmc_read_ext_csd(card); if (err) goto free_card; /* If doing byte addressing, check if required to do sector * addressing. Handle the case of <2GB cards needing sector * addressing. See section 8.1 JEDEC Standard JED84-A441; * ocr register has bit 30 set for sector addressing. */ if (!(mmc_card_blockaddr(card)) && (rocr & (1<<30))) mmc_card_set_blockaddr(card); /* Erase size depends on CSD and Extended CSD */ mmc_set_erase_size(card); } #if defined(CONFIG_ARCH_ACER_T20) || defined(CONFIG_ARCH_ACER_T30) if (card->cid.manfid == SANDISK_X3_CID_MID) { err = mmc_switch(card, 0x0, EXT_CSD_POWER_CLASS, 4); if (err) printk(KERN_ERR "%s: switch power class fail \n", mmc_hostname(card->host)); } #endif /* * If enhanced_area_en is TRUE, host needs to enable ERASE_GRP_DEF * bit. This bit will be lost every time after a reset or power off. */ if (card->ext_csd.enhanced_area_en) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_ERASE_GROUP_DEF, 1); if (err && err != -EBADMSG) goto free_card; if (err) { err = 0; /* * Just disable enhanced area off & sz * will try to enable ERASE_GROUP_DEF * during next time reinit */ card->ext_csd.enhanced_area_offset = -EINVAL; card->ext_csd.enhanced_area_size = -EINVAL; } else { card->ext_csd.erase_group_def = 1; /* * enable ERASE_GRP_DEF successfully. * This will affect the erase size, so * here need to reset erase size */ mmc_set_erase_size(card); } } /* * Activate high speed (if supported) */ if ((card->ext_csd.hs_max_dtr != 0) && (host->caps & MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); if (err && err != -EBADMSG) goto free_card; if (err) { printk(KERN_WARNING "%s: switch to highspeed failed\n", mmc_hostname(card->host)); err = 0; } else { mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } } /* * Enable HPI feature (if supported) */ if (card->ext_csd.hpi && (card->host->caps & MMC_CAP_BKOPS)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HPI_MGMT, 1); if (err && err != -EBADMSG) goto free_card; if (err) { pr_warning("%s: Enabling HPI failed\n", mmc_hostname(card->host)); err = 0; } else { card->ext_csd.hpi_en = 1; } } /* * Enable Background ops feature (if supported) */ if (card->ext_csd.bk_ops && (card->host->caps & MMC_CAP_BKOPS)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_EN, 1); if (err && err != -EBADMSG) goto free_card; if (err) { pr_warning("%s: Enabling BK ops failed\n", mmc_hostname(card->host)); err = 0; } else { card->ext_csd.bk_ops_en = 1; } } /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); /* * Indicate DDR mode (if supported). */ if (mmc_card_highspeed(card)) { if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) && ((host->caps & (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50)) == (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50))) ddr = MMC_1_8V_DDR_MODE; else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) && ((host->caps & (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50)) == (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50))) ddr = MMC_1_2V_DDR_MODE; } /* * Activate wide bus and DDR (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { static unsigned ext_csd_bits[][2] = { { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 }, { EXT_CSD_BUS_WIDTH_4, EXT_CSD_DDR_BUS_WIDTH_4 }, { EXT_CSD_BUS_WIDTH_1, EXT_CSD_BUS_WIDTH_1 }, }; static unsigned bus_widths[] = { MMC_BUS_WIDTH_8, MMC_BUS_WIDTH_4, MMC_BUS_WIDTH_1 }; unsigned idx, bus_width = 0; if (host->caps & MMC_CAP_8_BIT_DATA) idx = 0; else idx = 1; for (; idx < ARRAY_SIZE(bus_widths); idx++) { bus_width = bus_widths[idx]; if (bus_width == MMC_BUS_WIDTH_1) ddr = 0; /* no DDR for 1-bit width */ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][0]); if (!err) { mmc_set_bus_width(card->host, bus_width); /* * If controller can't handle bus width test, * use the highest bus width to maintain * compatibility with previous MMC behavior. */ if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) break; err = mmc_bus_test(card, bus_width); if (!err) break; } } if (!err && ddr) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][1]); } if (err) { printk(KERN_WARNING "%s: switch to bus width %d ddr %d " "failed\n", mmc_hostname(card->host), 1 << bus_width, ddr); goto free_card; } else if (ddr) { /* * eMMC cards can support 3.3V to 1.2V i/o (vccq) * signaling. * * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. * * 1.8V vccq at 3.3V core voltage (vcc) is not required * in the JEDEC spec for DDR. * * Do not force change in vccq since we are obviously * working and no change to vccq is needed. * * WARNING: eMMC rules are NOT the same as SD DDR */ if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) { err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); if (err) goto err; } mmc_card_set_ddr_mode(card); mmc_set_timing(card->host, MMC_TIMING_UHS_DDR50); mmc_set_bus_width(card->host, bus_width); } } if (!oldcard) host->card = card; #if defined(CONFIG_ARCH_ACER_T20) || defined(CONFIG_ARCH_ACER_T30) switch (card->type) { case MMC_TYPE_MMC: sprintf(emmc_type, "MMC"); break; case MMC_TYPE_SD: sprintf(emmc_type, "SD"); break; case MMC_TYPE_SDIO: sprintf(emmc_type, "SDIO"); break; case MMC_TYPE_SD_COMBO: sprintf(emmc_type, "SDcombo"); break; default: sprintf(emmc_type, "unknow"); } sprintf(emmc_date, "%02d/%04d", card->cid.month, card->cid.year); emmc_size = card->ext_csd.sectors >> 11; emmc_name = card->cid.prod_name; if (device_info_kobj == NULL) { device_info_kobj = kobject_create_and_add("dev-info_rom", NULL); if (device_info_kobj == NULL) { pr_warning("%s: subsystem_register failed\n", mmc_hostname(card->host)); } else { err = sysfs_create_group(device_info_kobj, &attr_group); if(err) { pr_warning("%s: sysfs_create_group failed\n", mmc_hostname(card->host)); } } } #endif return 0; free_card: if (!oldcard) mmc_remove_card(card); err: return err; }
/* * Handle the detection and initialisation of a card. * * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err, ddr = 0; int card_is_null = 0; u32 cid[4]; unsigned int max_dtr; u32 rocr; u8 *ext_csd = NULL; BUG_ON(!host); WARN_ON(!host->claimed); /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr); if (err) goto err; /* * For SPI, enable CRC as appropriate. */ if (mmc_host_is_spi(host)) { err = mmc_spi_set_crc(host, use_spi_crc); if (err) goto err; } /* * Fetch CID from card. */ if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else err = mmc_all_send_cid(host, cid); if (err) goto err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { err = -ENOENT; goto err; } card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host, &mmc_type); if (IS_ERR(card)) { err = PTR_ERR(card); goto err; } card->type = MMC_TYPE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); } /* * For native busses: set card RCA and quit open drain mode. */ if (!mmc_host_is_spi(host)) { err = mmc_set_relative_addr(card); if (err) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err) goto free_card; err = mmc_decode_csd(card); if (err) goto free_card; err = mmc_decode_cid(card); if (err) goto free_card; } /* * Select card, as all following commands rely on that. */ if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto free_card; } if (!oldcard) { /* * Fetch and process extended CSD. */ err = mmc_get_ext_csd(card, &ext_csd); if (err) goto free_card; err = mmc_read_ext_csd(card, ext_csd); if (err) goto free_card; /* If doing byte addressing, check if required to do sector * addressing. Handle the case of <2GB cards needing sector * addressing. See section 8.1 JEDEC Standard JED84-A441; * ocr register has bit 30 set for sector addressing. */ if (!(mmc_card_blockaddr(card)) && (rocr & (1<<30))) mmc_card_set_blockaddr(card); /* Erase size depends on CSD and Extended CSD */ mmc_set_erase_size(card); } /* * If enhanced_area_en is TRUE, host needs to enable ERASE_GRP_DEF * bit. This bit will be lost every time after a reset or power off. */ if (card->ext_csd.enhanced_area_en) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_ERASE_GROUP_DEF, 1, 0); if (err && err != -EBADMSG) goto free_card; if (err) { err = 0; /* * Just disable enhanced area off & sz * will try to enable ERASE_GROUP_DEF * during next time reinit */ card->ext_csd.enhanced_area_offset = -EINVAL; card->ext_csd.enhanced_area_size = -EINVAL; } else { card->ext_csd.erase_group_def = 1; /* * enable ERASE_GRP_DEF successfully. * This will affect the erase size, so * here need to reset erase size */ mmc_set_erase_size(card); } } /* * Ensure eMMC user default partition is enabled */ if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) { card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG, card->ext_csd.part_config, card->ext_csd.part_time); if (err && err != -EBADMSG) goto free_card; } /* * Activate high speed (if supported) */ if ((card->ext_csd.hs_max_dtr != 0) && (host->caps & MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1, 0); if (err && err != -EBADMSG) goto free_card; if (err) { printk(KERN_WARNING "%s: switch to highspeed failed\n", mmc_hostname(card->host)); err = 0; } else { mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } } /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); if (!host->card) { host->card = card; card_is_null = 1; } if (card->host->ops->execute_tuning) card->host->ops->execute_tuning(card->host); /* * Indicate DDR mode (if supported). */ if (mmc_card_highspeed(card)) { if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) && ((host->caps & (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50)) == (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50))) ddr = MMC_1_8V_DDR_MODE; else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) && ((host->caps & (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50)) == (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50))) ddr = MMC_1_2V_DDR_MODE; } /* * Activate wide bus and DDR (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { static unsigned ext_csd_bits[][2] = { { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 }, { EXT_CSD_BUS_WIDTH_4, EXT_CSD_DDR_BUS_WIDTH_4 }, { EXT_CSD_BUS_WIDTH_1, EXT_CSD_BUS_WIDTH_1 }, }; static unsigned bus_widths[] = { MMC_BUS_WIDTH_8, MMC_BUS_WIDTH_4, MMC_BUS_WIDTH_1 }; unsigned idx, bus_width = 0; if (host->caps & MMC_CAP_8_BIT_DATA) idx = 0; else idx = 1; for (; idx < ARRAY_SIZE(bus_widths); idx++) { bus_width = bus_widths[idx]; if (bus_width == MMC_BUS_WIDTH_1) ddr = 0; /* no DDR for 1-bit width */ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][0], 0); if (!err) { mmc_set_bus_width(card->host, bus_width); /* * If controller can't handle bus width test, * compare ext_csd previously read in 1 bit mode * against ext_csd at new bus width */ if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) { /* err = mmc_compare_ext_csds(card, ext_csd, bus_width); */ } else err = mmc_bus_test(card, bus_width); if (!err) break; } } if (!err && ddr) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][1], 0); } if (err) { printk(KERN_WARNING "%s: switch to bus width %d ddr %d " "failed\n", mmc_hostname(card->host), 1 << bus_width, ddr); if (card_is_null) host->card = NULL; goto free_card; } else if (ddr) { /* * eMMC cards can support 3.3V to 1.2V i/o (vccq) * signaling. * * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq. * * 1.8V vccq at 3.3V core voltage (vcc) is not required * in the JEDEC spec for DDR. * * Do not force change in vccq since we are obviously * working and no change to vccq is needed. * * WARNING: eMMC rules are NOT the same as SD DDR */ if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) { err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0); if (err) { if (card_is_null) host->card = NULL; goto err; } } mmc_card_set_ddr_mode(card); mmc_set_timing(card->host, MMC_TIMING_UHS_DDR50); mmc_set_bus_width(card->host, bus_width); } } if (!oldcard) host->card = card; if (card->host->ops->execute_tuning) card->host->ops->execute_tuning(card->host); mmc_free_ext_csd(ext_csd); return 0; free_card: if (!oldcard) mmc_remove_card(card); err: mmc_free_ext_csd(ext_csd); return err; }
static int autok_thread_func(void *data) { struct sdio_autok_thread_data *autok_thread_data; //struct sched_param param = { .sched_priority = 99 }; unsigned int vcore_uv = 0; struct msdc_host *host; struct mmc_host *mmc; char stage = 0; int i,j; int res = 0; int doStg2 = 0; void __iomem *base; u32 dma; struct timeval t0,t1; int time_in_s, time_in_ms; // unsigned long flags; autok_thread_data = (struct sdio_autok_thread_data *)data; //sched_setscheduler(current, SCHED_FIFO, ¶m); // preempt_disable(); host = autok_thread_data->host; mmc = host->mmc; stage = autok_thread_data->stage; base = host->base; dma = msdc_dma_status(); // Inform msdc_set_mclk() auto-K is going to process sdio_autok_processed = 1; // Set clock to card max clock mmc_set_clock(mmc, mmc->ios.clock); msdc_sdio_set_long_timing_delay_by_freq(host, mmc->ios.clock); msdc_ungate_clock(host); // Set PIO mode msdc_dma_off(); vcore_uv = autok_get_current_vcore_offset(); // End of initialize do_gettimeofday(&t0); if(autok_thread_data->log != NULL) log_info = autok_thread_data->log; if(stage == 1) { // call stage 1 auto-K callback function autok_thread_data->is_autok_done[host->id] = 0; res = msdc_autok_stg1_cal(host, vcore_uv, autok_thread_data->p_autok_predata); if(res){ pr_debug("[%s] Auto-K stage 1 fail, res = %d, set msdc parameter settings stored in nvram to 0\n", __func__, res); memset(autok_thread_data->p_autok_predata->ai_data[0], 0, autok_thread_data->p_autok_predata->param_count * sizeof(unsigned int)); autok_thread_data->is_autok_done[host->id] = 2; } // For Abort function if(atomic_read(&autok_is_abort) == 1){ autok_thread_data->is_autok_done[host->id] = 3; } } else if(stage == 2) { // call stage 2 auto-K callback function // check if msdc params of different volt are all 0, if so, that means auto-K stg1 failed for(i=0; i<autok_thread_data->p_autok_predata->vol_count; i++){ for(j=0; j<autok_thread_data->p_autok_predata->param_count; j++){ if(autok_thread_data->p_autok_predata->ai_data[i][j].data.sel != 0){ doStg2 = 1; break; } } if(doStg2) break; } if(doStg2){ res = msdc_autok_stg2_cal(host, autok_thread_data->p_autok_predata, vcore_uv); if(res){ pr_debug("[%s] Auto-K stage 2 fail, res = %d, downgrade SDIO freq to 50MHz\n", __func__, res); mmc->ios.clock = 50*1000*1000; mmc_set_clock(mmc, mmc->ios.clock); msdc_sdio_set_long_timing_delay_by_freq(host, mmc->ios.clock); sdio_autok_processed = 0; for (i = 0; i < HOST_MAX_NUM; i++) { if (autok_thread_data->p_autok_progress[i].host_id == -1) { break; } else if (autok_thread_data->p_autok_progress[i].host_id == host->id) { autok_thread_data->p_autok_progress[i].fail = 1; } } } } else { // Auto-K stg1 failed pr_debug("[%s] Auto-K stage 1 fail, downgrade SDIO freq to 50MHz\n", __func__); mmc->ios.clock = 50*1000*1000; mmc_set_clock(mmc, mmc->ios.clock); msdc_sdio_set_long_timing_delay_by_freq(host, mmc->ios.clock); sdio_autok_processed = 0; for (i = 0; i < HOST_MAX_NUM; i++) { if (autok_thread_data->p_autok_progress[i].host_id == -1) { break; } else if (autok_thread_data->p_autok_progress[i].host_id == host->id) { autok_thread_data->p_autok_progress[i].fail = 1; } } } log_info = NULL; } else { pr_debug("[%s] stage %d doesn't support in auto-K\n", __func__, stage); //return -EFAULT; } do_gettimeofday(&t1); if(dma == DMA_ON) msdc_dma_on(); msdc_gate_clock(host,1); // [FIXDONE] Tell native module that auto-K has finished if(stage == 1) autok_calibration_done(host->id, autok_thread_data); else if(stage == 2){ for(i=0; i<HOST_MAX_NUM; i++){ if(autok_thread_data->p_autok_progress[i].host_id == -1){ break; } else if(autok_thread_data->p_autok_progress[i].host_id == host->id){ autok_thread_data->p_autok_progress[i].done = 1; if(autok_thread_data->p_autok_progress[i].done > 0) complete(&autok_thread_data->autok_completion[i]); } } } time_in_s = (t1.tv_sec - t0.tv_sec); time_in_ms = (t1.tv_usec - t0.tv_usec)>>10; pr_err("\n[AUTOKK][Stage%d] Timediff is %d.%d(s)\n", (int)stage, time_in_s, time_in_ms ); // preempt_enable(); return 0; }
/* * Handle the detection and initialisation of a card. * * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err; u32 cid[4]; unsigned int max_dtr; #ifdef CONFIG_MMC_PARANOID_SD_INIT int retries; #endif BUG_ON(!host); WARN_ON(!host->claimed); /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* * If SD_SEND_IF_COND indicates an SD 2.0 * compliant card and we should set bit 30 * of the ocr to indicate that we can handle * block-addressed SDHC cards. */ err = mmc_send_if_cond(host, ocr); if (!err) ocr |= 1 << 30; err = mmc_send_app_op_cond(host, ocr, NULL); if (err) goto err; /* * Fetch CID from card. */ if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else err = mmc_all_send_cid(host, cid); if (err) goto err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { err = -ENOENT; goto err; } card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host, &sd_type); if (IS_ERR(card)) { err = PTR_ERR(card); goto err; } card->type = MMC_TYPE_SD; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); } /* * For native busses: get card RCA and quit open drain mode. */ if (!mmc_host_is_spi(host)) { err = mmc_send_relative_addr(host, &card->rca); if (err) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err) goto free_card; err = mmc_decode_csd(card); if (err) goto free_card; mmc_decode_cid(card); } /* * Select card, as all following commands rely on that. */ if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto free_card; } if (!oldcard) { /* * Fetch SCR from card. */ err = mmc_app_send_scr(card, card->raw_scr); if (err) goto free_card; err = mmc_decode_scr(card); if (err < 0) goto free_card; /* * Fetch switch information from card. */ #ifdef CONFIG_MMC_PARANOID_SD_INIT for (retries = 1; retries <= 3; retries++) { err = mmc_read_switch(card); if (!err) { if (retries > 1) { printk(KERN_WARNING "%s: recovered\n", mmc_hostname(host)); } break; } else { printk(KERN_WARNING "%s: read switch failed (attempt %d)\n", mmc_hostname(host), retries); } } #else err = mmc_read_switch(card); #endif if (err) goto free_card; } /* * For SPI, enable CRC as appropriate. * This CRC enable is located AFTER the reading of the * card registers because some SDHC cards are not able * to provide valid CRCs for non-512-byte blocks. */ if (mmc_host_is_spi(host)) { err = mmc_spi_set_crc(host, use_spi_crc); if (err) goto free_card; } /* * Attempt to change to high-speed (if supported) */ err = mmc_switch_hs(card); if (err) goto free_card; /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->sw_caps.hs_max_dtr) max_dtr = card->sw_caps.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); /* * Switch to wider bus (if supported). */ if ((host->caps & MMC_CAP_4_BIT_DATA) && (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); if (err) goto free_card; mmc_set_bus_width(host, MMC_BUS_WIDTH_4); } /* * Check if read-only switch is active. */ if (!oldcard) { if (!host->ops->get_ro || host->ops->get_ro(host) < 0) { printk(KERN_WARNING "%s: host does not " "support reading read-only " "switch. assuming write-enable.\n", mmc_hostname(host)); } else { if (host->ops->get_ro(host) > 0) mmc_card_set_readonly(card); } } if (!oldcard) host->card = card; return 0; free_card: if (!oldcard) mmc_remove_card(card); err: return err; }
/* * Given a 128-bit response, decode to our card CSD structure. */ static int mmc_decode_csd(struct mmc_card *card) { struct mmc_csd *csd = &card->csd; unsigned int e, m, csd_struct; u32 *resp = card->raw_csd; /* * We only understand CSD structure v1.1 and v1.2. * v1.2 has extra information in bits 15, 11 and 10. */ csd_struct = UNSTUFF_BITS(resp, 126, 2); #if defined(CONFIG_MACH_OMAP3630_EDP1) || defined(CONFIG_MACH_OMAP3621_EDP1) || defined(CONFIG_MACH_OMAP3621_BOXER) || defined(CONFIG_MACH_OMAP3621_EVT1A) || defined(CONFIG_MACH_OMAP3621_GOSSAMER) /* To recognize Boxer board eMMC */ if (csd_struct != 1 && csd_struct != 2 && csd_struct != 3) { #else if (csd_struct != 1 && csd_struct != 2) { #endif printk(KERN_ERR "%s: unrecognised CSD structure version %d\n", mmc_hostname(card->host), csd_struct); return -EINVAL; } csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4); m = UNSTUFF_BITS(resp, 115, 4); e = UNSTUFF_BITS(resp, 112, 3); csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; m = UNSTUFF_BITS(resp, 99, 4); e = UNSTUFF_BITS(resp, 96, 3); csd->max_dtr = tran_exp[e] * tran_mant[m]; csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); e = UNSTUFF_BITS(resp, 47, 3); m = UNSTUFF_BITS(resp, 62, 12); csd->capacity = (1 + m) << (e + 2); csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); csd->read_partial = UNSTUFF_BITS(resp, 79, 1); csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); csd->write_partial = UNSTUFF_BITS(resp, 21, 1); return 0; } /* * Read and decode extended CSD. */ static int mmc_read_ext_csd(struct mmc_card *card) { int err; u8 *ext_csd; BUG_ON(!card); if (card->csd.mmca_vsn < CSD_SPEC_VER_4) return 0; /* * As the ext_csd is so large and mostly unused, we don't store the * raw block in mmc_card. */ ext_csd = kmalloc(512, GFP_KERNEL); if (!ext_csd) { printk(KERN_ERR "%s: could not allocate a buffer to " "receive the ext_csd.\n", mmc_hostname(card->host)); return -ENOMEM; } err = mmc_send_ext_csd(card, ext_csd); if (err) { /* * We all hosts that cannot perform the command * to fail more gracefully */ if (err != -EINVAL) goto out; /* * High capacity cards should have this "magic" size * stored in their CSD. */ if (card->csd.capacity == (4096 * 512)) { printk(KERN_ERR "%s: unable to read EXT_CSD " "on a possible high capacity card. " "Card will be ignored.\n", mmc_hostname(card->host)); } else { printk(KERN_WARNING "%s: unable to read " "EXT_CSD, performance might " "suffer.\n", mmc_hostname(card->host)); err = 0; } goto out; } card->ext_csd.rev = ext_csd[EXT_CSD_REV]; #if defined(CONFIG_MACH_OMAP3630_EDP1) || defined(CONFIG_MACH_OMAP3621_EDP1) || defined(CONFIG_MACH_OMAP3621_BOXER) || defined(CONFIG_MACH_OMAP3621_EVT1A) || defined(CONFIG_MACH_OMAP3621_GOSSAMER) /* To recognize Boxer board eMMC */ if (card->ext_csd.rev > 5) { #else if (card->ext_csd.rev > 2) { #endif printk(KERN_ERR "%s: unrecognised EXT_CSD structure " "version %d\n", mmc_hostname(card->host), card->ext_csd.rev); err = -EINVAL; goto out; } #ifdef CONFIG_HC_Broken_eMMC_ZOOM2 /* * Hack: eMMC on Zoom2 seems to have a lower EXT_CSD Rev. * This is incorrect as it is an HC card. The card becomes * unusable if not set to blockaddr mode. * The low level driver sets up the unused bit for MMC2 on Zoom2. * Revert this hack once it is fixed in the card. */ if (card->host->unused) { card->ext_csd.sectors = ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; if (card->ext_csd.sectors) mmc_card_set_blockaddr(card); } else #endif if (card->ext_csd.rev >= 2) { card->ext_csd.sectors = ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; if (mmc_card_blockaddr(card)) mmc_card_set_blockaddr(card); } /* disable DDR detection */ ext_csd[EXT_CSD_CARD_TYPE] &= EXT_CSD_CARD_TYPE_MASK; switch (ext_csd[EXT_CSD_CARD_TYPE]) { case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: card->ext_csd.hs_max_dtr = 52000000; break; case EXT_CSD_CARD_TYPE_26: card->ext_csd.hs_max_dtr = 26000000; break; default: /* MMC v4 spec says this cannot happen */ printk(KERN_WARNING "%s: card is mmc v4 but doesn't " "support any high-speed modes.\n", mmc_hostname(card->host)); goto out; } if (card->ext_csd.rev >= 3) { u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT]; /* Sleep / awake timeout in 100ns units */ if (sa_shift > 0 && sa_shift <= 0x17) card->ext_csd.sa_timeout = 1 << ext_csd[EXT_CSD_S_A_TIMEOUT]; else{ card->ext_csd.sa_timeout = MMC_SLEEP_TIMEOUT_DEFAULT; printk(KERN_WARNING "%s: card's S_A_TIMEOUT is out of range.\n",mmc_hostname(card->host)); } } out: kfree(ext_csd); return err; } MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1], card->raw_cid[2], card->raw_cid[3]); MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1], card->raw_csd[2], card->raw_csd[3]); MMC_DEV_ATTR(date, "%02d/%04d\n", card->cid.month, card->cid.year); MMC_DEV_ATTR(fwrev, "0x%x\n", card->cid.fwrev); MMC_DEV_ATTR(hwrev, "0x%x\n", card->cid.hwrev); MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid); MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name); MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid); MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial); static struct attribute *mmc_std_attrs[] = { &dev_attr_cid.attr, &dev_attr_csd.attr, &dev_attr_date.attr, &dev_attr_fwrev.attr, &dev_attr_hwrev.attr, &dev_attr_manfid.attr, &dev_attr_name.attr, &dev_attr_oemid.attr, &dev_attr_serial.attr, NULL, }; static struct attribute_group mmc_std_attr_group = { .attrs = mmc_std_attrs, }; static struct attribute_group *mmc_attr_groups[] = { &mmc_std_attr_group, NULL, }; static struct device_type mmc_type = { .groups = mmc_attr_groups, }; /* * Handle the detection and initialisation of a card. * * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err; u32 cid[4]; u32 rocr; unsigned int max_dtr; BUG_ON(!host); WARN_ON(!host->claimed); /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr); if (err) goto err; /* * For SPI, enable CRC as appropriate. */ if (mmc_host_is_spi(host)) { err = mmc_spi_set_crc(host, use_spi_crc); if (err) goto err; } /* * Fetch CID from card. */ if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else err = mmc_all_send_cid(host, cid); if (err) goto err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { err = -ENOENT; goto err; } card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host, &mmc_type); if (IS_ERR(card)) { err = PTR_ERR(card); goto err; } card->type = MMC_TYPE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); /* * If the OCR response to OP_COND from * the card ack block addressing then * enable it */ if (rocr & MMC_CARD_ACCESS_MODE_MASK) mmc_card_set_blockaddr(card); } /* * For native busses: set card RCA and quit open drain mode. */ if (!mmc_host_is_spi(host)) { err = mmc_set_relative_addr(card); if (err) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err) goto free_card; err = mmc_decode_csd(card); if (err) goto free_card; err = mmc_decode_cid(card); if (err) goto free_card; } /* * Select card, as all following commands rely on that. */ if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto free_card; } if (!oldcard) { /* * Fetch and process extended CSD. */ err = mmc_read_ext_csd(card); if (err) goto free_card; } /* * Activate high speed (if supported) */ if ((card->ext_csd.hs_max_dtr != 0) && (host->caps & MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); if (err) goto free_card; mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); /* * Activate wide bus (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { unsigned ext_csd_bit, bus_width; if (host->caps & MMC_CAP_8_BIT_DATA) { ext_csd_bit = EXT_CSD_BUS_WIDTH_8; bus_width = MMC_BUS_WIDTH_8; } else { ext_csd_bit = EXT_CSD_BUS_WIDTH_4; bus_width = MMC_BUS_WIDTH_4; } err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bit); if (err) goto free_card; mmc_set_bus_width(card->host, bus_width); } if (!oldcard) host->card = card; return 0; free_card: if (!oldcard) mmc_remove_card(card); err: return err; } /* * Host is being removed. Free up the current card. */ static void mmc_remove(struct mmc_host *host) { BUG_ON(!host); BUG_ON(!host->card); mmc_remove_card(host->card); host->card = NULL; }
/* * Handle the detection and initialisation of a card. * * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err, ddr = 0; u32 cid[4]; unsigned int max_dtr; BUG_ON(!host); WARN_ON(!host->claimed); /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); if (err) goto err; /* * For SPI, enable CRC as appropriate. */ if (mmc_host_is_spi(host)) { err = mmc_spi_set_crc(host, use_spi_crc); if (err) goto err; } /* * Fetch CID from card. */ if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else err = mmc_all_send_cid(host, cid); if (err) goto err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { err = -ENOENT; goto err; } card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host, &mmc_type); if (IS_ERR(card)) { err = PTR_ERR(card); goto err; } card->type = MMC_TYPE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); } /* * For native busses: set card RCA and quit open drain mode. */ if (!mmc_host_is_spi(host)) { err = mmc_set_relative_addr(card); if (err) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err) goto free_card; err = mmc_decode_csd(card); if (err) goto free_card; err = mmc_decode_cid(card); if (err) goto free_card; } /* * Select card, as all following commands rely on that. */ if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto free_card; } if (!oldcard) { /* * Fetch and process extended CSD. */ err = mmc_read_ext_csd(card); if (err) goto free_card; } /* * Activate high speed (if supported) */ if ((card->ext_csd.hs_max_dtr != 0) && (host->caps & MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); if (err && err != -EBADMSG) goto free_card; if (err) { printk(KERN_WARNING "%s: switch to highspeed failed\n", mmc_hostname(card->host)); err = 0; } else { mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } } /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); /* * Indicate DDR mode (if supported). */ if (mmc_card_highspeed(card)) { if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) && (host->caps & (MMC_CAP_1_8V_DDR))) ddr = MMC_1_8V_DDR_MODE; else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) && (host->caps & (MMC_CAP_1_2V_DDR))) ddr = MMC_1_2V_DDR_MODE; } /* * Activate wide bus and DDR (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { unsigned ext_csd_bit, bus_width; if (host->caps & MMC_CAP_8_BIT_DATA) { if (ddr) ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_8; else ext_csd_bit = EXT_CSD_BUS_WIDTH_8; bus_width = MMC_BUS_WIDTH_8; } else { if (ddr) ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_4; else ext_csd_bit = EXT_CSD_BUS_WIDTH_4; bus_width = MMC_BUS_WIDTH_4; } err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bit); if (err && err != -EBADMSG) goto free_card; if (err) { printk(KERN_WARNING "%s: switch to bus width %d ddr %d " "failed\n", mmc_hostname(card->host), 1 << bus_width, ddr); err = 0; } else { if (ddr) mmc_card_set_ddr_mode(card); else ddr = MMC_SDR_MODE; mmc_set_bus_width_ddr(card->host, bus_width, ddr); } } if (!oldcard) host->card = card; return 0; free_card: if (!oldcard) mmc_remove_card(card); err: return err; }
/* * Handle the detection and initialisation of a card. * * In the case of a resume, "oldcard" will contain the card * we're trying to reinitialise. */ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; int err, ddr = 0; u32 cid[4]; unsigned int max_dtr; u32 rocr; BUG_ON(!host); WARN_ON(!host->claimed); /* * Since we're changing the OCR value, we seem to * need to tell some cards to go back to the idle * state. We wait 1ms to give cards time to * respond. */ mmc_go_idle(host); /* The extra bit indicates that we support high capacity */ err = mmc_send_op_cond(host, ocr | (1 << 30), &rocr); if (err) goto err; /* * For SPI, enable CRC as appropriate. */ if (mmc_host_is_spi(host)) { err = mmc_spi_set_crc(host, use_spi_crc); if (err) goto err; } /* * Fetch CID from card. */ if (mmc_host_is_spi(host)) err = mmc_send_cid(host, cid); else err = mmc_all_send_cid(host, cid); if (err) goto err; if (oldcard) { if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) { err = -ENOENT; goto err; } card = oldcard; } else { /* * Allocate card structure. */ card = mmc_alloc_card(host, &mmc_type); if (IS_ERR(card)) { err = PTR_ERR(card); goto err; } card->type = MMC_TYPE_MMC; card->rca = 1; memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); } /* * For native busses: set card RCA and quit open drain mode. */ if (!mmc_host_is_spi(host)) { err = mmc_set_relative_addr(card); if (err) goto free_card; mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); } if (!oldcard) { /* * Fetch CSD from card. */ err = mmc_send_csd(card, card->raw_csd); if (err) goto free_card; err = mmc_decode_csd(card); if (err) goto free_card; err = mmc_decode_cid(card); if (err) goto free_card; } /* * Select card, as all following commands rely on that. */ if (!mmc_host_is_spi(host)) { err = mmc_select_card(card); if (err) goto free_card; } if (!oldcard) { /* * Fetch and process extended CSD. */ err = mmc_read_ext_csd(card); if (err) goto free_card; /* If doing byte addressing, check if required to do sector * addressing. Handle the case of <2GB cards needing sector * addressing. See section 8.1 JEDEC Standard JED84-A441; * ocr register has bit 30 set for sector addressing. */ if (!(mmc_card_blockaddr(card)) && (rocr & (1<<30))) mmc_card_set_blockaddr(card); /* Erase size depends on CSD and Extended CSD */ mmc_set_erase_size(card); } /* * If enhanced_area_en is TRUE, host needs to enable ERASE_GRP_DEF * bit. This bit will be lost everytime after a reset or power off. */ if (card->ext_csd.enhanced_area_en) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_ERASE_GROUP_DEF, 1); if (err && err != -EBADMSG) goto free_card; if (err) { err = 0; /* * Just disable enhanced area off & sz * will try to enable ERASE_GROUP_DEF * during next time reinit */ card->ext_csd.enhanced_area_offset = -EINVAL; card->ext_csd.enhanced_area_size = -EINVAL; } else { card->ext_csd.erase_group_def = 1; /* * enable ERASE_GRP_DEF successfully. * This will affect the erase size, so * here need to reset erase size */ mmc_set_erase_size(card); } } /* * Activate high speed (if supported) */ if ((card->ext_csd.hs_max_dtr != 0) && (host->caps & MMC_CAP_MMC_HIGHSPEED)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); if (err && err != -EBADMSG) goto free_card; if (err) { printk(KERN_WARNING "%s: switch to highspeed failed\n", mmc_hostname(card->host)); err = 0; } else { mmc_card_set_highspeed(card); mmc_set_timing(card->host, MMC_TIMING_MMC_HS); } } /* * Compute bus speed. */ max_dtr = (unsigned int)-1; if (mmc_card_highspeed(card)) { if (max_dtr > card->ext_csd.hs_max_dtr) max_dtr = card->ext_csd.hs_max_dtr; } else if (max_dtr > card->csd.max_dtr) { max_dtr = card->csd.max_dtr; } mmc_set_clock(host, max_dtr); /* * Indicate DDR mode (if supported). */ if (mmc_card_highspeed(card)) { if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) && (host->caps & (MMC_CAP_1_8V_DDR))) ddr = MMC_1_8V_DDR_MODE; else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) && (host->caps & (MMC_CAP_1_2V_DDR))) ddr = MMC_1_2V_DDR_MODE; } /* * Activate wide bus and DDR (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { static unsigned ext_csd_bits[][2] = { { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 }, { EXT_CSD_BUS_WIDTH_4, EXT_CSD_DDR_BUS_WIDTH_4 }, { EXT_CSD_BUS_WIDTH_1, EXT_CSD_BUS_WIDTH_1 }, }; static unsigned bus_widths[] = { MMC_BUS_WIDTH_8, MMC_BUS_WIDTH_4, MMC_BUS_WIDTH_1 }; unsigned idx, bus_width = 0; if (host->caps & MMC_CAP_8_BIT_DATA) idx = 0; else idx = 1; for (; idx < ARRAY_SIZE(bus_widths); idx++) { bus_width = bus_widths[idx]; if (bus_width == MMC_BUS_WIDTH_1) ddr = 0; /* no DDR for 1-bit width */ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][0]); if (!err) { mmc_set_bus_width_ddr(card->host, bus_width, MMC_SDR_MODE); /* * If controller can't handle bus width test, * use the highest bus width to maintain * compatibility with previous MMC behavior. */ if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) break; err = mmc_bus_test(card, bus_width); if (!err) break; } } if (!err && ddr) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, ext_csd_bits[idx][1]); } if (err) { printk(KERN_WARNING "%s: switch to bus width %d ddr %d " "failed\n", mmc_hostname(card->host), 1 << bus_width, ddr); goto free_card; } else if (ddr) { mmc_card_set_ddr_mode(card); mmc_set_bus_width_ddr(card->host, bus_width, ddr); } } if (!oldcard) host->card = card; return 0; free_card: if (!oldcard) mmc_remove_card(card); err: return err; }