9
0
Fork 0

Merge branch 'for-next/mci'

Conflicts:
	arch/arm/boards/tqma53/board.c
This commit is contained in:
Sascha Hauer 2014-02-03 09:55:52 +01:00
commit d3c96d6522
4 changed files with 97 additions and 19 deletions

View File

@ -42,5 +42,7 @@ struct esdhc_platform_data {
enum cd_types cd_type;
unsigned caps;
char *devname;
unsigned dsr_val;
int use_dsr;
};
#endif /* __ASM_ARCH_IMX_ESDHC_H */

View File

@ -582,6 +582,10 @@ static int fsl_esdhc_probe(struct device_d *dev)
if (host->mci.f_min < 200000)
host->mci.f_min = 200000;
host->mci.f_max = rate;
if (pdata) {
host->mci.use_dsr = pdata->use_dsr;
host->mci.dsr_val = pdata->dsr_val;
}
mci_of_parse(&host->mci);

View File

@ -101,6 +101,20 @@ static void mci_setup_cmd(struct mci_cmd *p, unsigned cmd, unsigned arg, unsigne
p->resp_type = response;
}
/**
* configure optional DSR value
* @param mci_dev MCI instance
* @return Transaction status (0 on success)
*/
static int mci_set_dsr(struct mci *mci)
{
struct mci_cmd cmd;
mci_setup_cmd(&cmd, MMC_CMD_SET_DSR,
(mci->host->dsr_val >> 16) | 0xffff, MMC_RSP_NONE);
return mci_send_cmd(mci, &cmd, NULL);
}
/**
* Setup SD/MMC card's blocklength to be used for future transmitts
* @param mci_dev MCI instance
@ -695,7 +709,6 @@ static void mci_set_bus_width(struct mci *mci, unsigned width)
static void mci_detect_version_from_csd(struct mci *mci)
{
int version;
char *vstr;
if (mci->version == MMC_VERSION_UNKNOWN) {
/* the version is coded in the bits 127:126 (left aligned) */
@ -703,32 +716,52 @@ static void mci_detect_version_from_csd(struct mci *mci)
switch (version) {
case 0:
vstr = "1.2";
mci->version = MMC_VERSION_1_2;
break;
case 1:
vstr = "1.4";
mci->version = MMC_VERSION_1_4;
break;
case 2:
vstr = "2.2";
mci->version = MMC_VERSION_2_2;
break;
case 3:
vstr = "3.0";
mci->version = MMC_VERSION_3;
break;
case 4:
vstr = "4.0";
mci->version = MMC_VERSION_4;
break;
default:
vstr = "unknown, fallback to 1.2";
printf("unknown card version, fallback to 1.02\n");
mci->version = MMC_VERSION_1_2;
break;
}
}
}
dev_info(&mci->dev, "detected card version %s\n", vstr);
/**
* correct the version from ext_csd data if it's not an SD-card, detected
* version is at least 4 and we have ext_csd data
*/
static void mci_correct_version_from_ext_csd(struct mci *mci)
{
if (!IS_SD(mci) && (mci->version >= MMC_VERSION_4) && mci->ext_csd) {
switch (mci->ext_csd[EXT_CSD_REV]) {
case 1:
mci->version = MMC_VERSION_4_1;
break;
case 2:
mci->version = MMC_VERSION_4_2;
break;
case 3:
mci->version = MMC_VERSION_4_3;
break;
case 5:
mci->version = MMC_VERSION_4_41;
break;
case 6:
mci->version = MMC_VERSION_4_5;
break;
}
}
}
@ -836,6 +869,15 @@ static void mci_extract_card_capacity_from_csd(struct mci *mci)
dev_dbg(&mci->dev, "Capacity: %u MiB\n", (unsigned)(mci->capacity >> 20));
}
/**
* Extract card's DSR implementation state from CSD
* @param mci MCI instance
*/
static void mci_extract_card_dsr_imp_from_csd(struct mci *mci)
{
mci->dsr_imp = UNSTUFF_BITS(mci->csd, 76, 1);
}
static int mmc_compare_ext_csds(struct mci *mci, unsigned bus_width)
{
u8 *bw_ext_csd;
@ -1058,6 +1100,7 @@ static int mci_startup(struct mci *mci)
mci_detect_version_from_csd(mci);
mci_extract_max_tran_speed_from_csd(mci);
mci_extract_block_lengths_from_csd(mci);
mci_extract_card_dsr_imp_from_csd(mci);
/* sanitiy? */
if (mci->read_bl_len > SECTOR_SIZE) {
@ -1074,6 +1117,9 @@ static int mci_startup(struct mci *mci)
dev_dbg(&mci->dev, "Read block length: %u, Write block length: %u\n",
mci->read_bl_len, mci->write_bl_len);
if (mci->dsr_imp && mci->host->use_dsr)
mci_set_dsr(mci);
if (!mmc_host_is_spi(host)) { /* cmd not supported in spi */
dev_dbg(&mci->dev, "Select the card, and put it into Transfer Mode\n");
/* Select the card, and put it into Transfer Mode */
@ -1093,6 +1139,9 @@ static int mci_startup(struct mci *mci)
if (err)
return err;
mci_correct_version_from_ext_csd(mci);
printf("detected %s card version %d.%d\n", IS_SD(mci) ? "SD" : "MMC",
(mci->version >> 8) & 0xf, mci->version & 0xff);
mci_extract_card_capacity_from_csd(mci);
if (IS_SD(mci))
@ -1376,10 +1425,17 @@ static unsigned extract_mtd_month(struct mci *mci)
*/
static unsigned extract_mtd_year(struct mci *mci)
{
unsigned year;
if (IS_SD(mci))
return UNSTUFF_BITS(mci->cid, 12, 8) + 2000;
else
year = UNSTUFF_BITS(mci->cid, 12, 8) + 2000;
else if (mci->version < MMC_VERSION_4_41)
return UNSTUFF_BITS(mci->cid, 8, 4) + 1997;
else {
year = UNSTUFF_BITS(mci->cid, 8, 4) + 1997;
if (year < 2010)
year += 16;
}
return year;
}
static void mci_print_caps(unsigned caps)
@ -1426,7 +1482,7 @@ static void mci_info(struct device_d *dev)
(mci->version >> 4) & 0xf, mci->version & 0xf);
} else {
printf(" Attached is an SD Card (Version: %u.%u)\n",
(mci->version >> 4) & 0xf, mci->version & 0xf);
(mci->version >> 8) & 0xf, mci->version & 0xff);
}
printf(" Capacity: %u MiB\n", (unsigned)(mci->capacity >> 20));
@ -1719,6 +1775,7 @@ void mci_of_parse(struct mci_host *host)
{
struct device_node *np;
u32 bus_width;
u32 dsr_val;
if (!IS_ENABLED(CONFIG_OFDEVICE))
return;
@ -1751,4 +1808,11 @@ void mci_of_parse(struct mci_host *host)
/* f_max is obtained from the optional "max-frequency" property */
of_property_read_u32(np, "max-frequency", &host->f_max);
if (!of_property_read_u32(np, "dsr", &dsr_val)) {
if (dsr_val < 0x10000) {
host->use_dsr = 1;
host->dsr_val = dsr_val;
}
}
}

View File

@ -31,18 +31,23 @@
/* Firmware revisions for SD cards */
#define SD_VERSION_SD 0x20000
#define SD_VERSION_2 (SD_VERSION_SD | 0x20)
#define SD_VERSION_1_0 (SD_VERSION_SD | 0x10)
#define SD_VERSION_1_10 (SD_VERSION_SD | 0x1a)
#define SD_VERSION_2 (SD_VERSION_SD | 0x200)
#define SD_VERSION_1_0 (SD_VERSION_SD | 0x100)
#define SD_VERSION_1_10 (SD_VERSION_SD | 0x10a)
/* Firmware revisions for MMC cards */
#define MMC_VERSION_MMC 0x10000
#define MMC_VERSION_UNKNOWN (MMC_VERSION_MMC)
#define MMC_VERSION_1_2 (MMC_VERSION_MMC | 0x12)
#define MMC_VERSION_1_4 (MMC_VERSION_MMC | 0x14)
#define MMC_VERSION_2_2 (MMC_VERSION_MMC | 0x22)
#define MMC_VERSION_3 (MMC_VERSION_MMC | 0x30)
#define MMC_VERSION_4 (MMC_VERSION_MMC | 0x40)
#define MMC_VERSION_1_2 (MMC_VERSION_MMC | 0x102)
#define MMC_VERSION_1_4 (MMC_VERSION_MMC | 0x104)
#define MMC_VERSION_2_2 (MMC_VERSION_MMC | 0x202)
#define MMC_VERSION_3 (MMC_VERSION_MMC | 0x300)
#define MMC_VERSION_4 (MMC_VERSION_MMC | 0x400)
#define MMC_VERSION_4_1 (MMC_VERSION_MMC | 0x401)
#define MMC_VERSION_4_2 (MMC_VERSION_MMC | 0x402)
#define MMC_VERSION_4_3 (MMC_VERSION_MMC | 0x403)
#define MMC_VERSION_4_41 (MMC_VERSION_MMC | 0x429)
#define MMC_VERSION_4_5 (MMC_VERSION_MMC | 0x405)
#define MMC_CAP_SPI (1 << 0)
#define MMC_CAP_4_BIT_DATA (1 << 1)
@ -294,6 +299,8 @@ struct mci_host {
unsigned clock; /**< Current clock used to talk to the card */
unsigned bus_width; /**< used data bus width to the card */
unsigned max_req_size;
unsigned dsr_val; /**< optional dsr value */
int use_dsr; /**< optional dsr usage flag */
/** init the host interface */
int (*init)(struct mci_host*, struct device_d*);
@ -344,6 +351,7 @@ struct mci {
unsigned write_bl_len;
uint64_t capacity; /**< Card's data capacity in bytes */
int ready_for_use; /** true if already probed */
int dsr_imp; /**< DSR implementation state from CSD */
char *ext_csd;
int probe;
struct param_d *param_probe;