Merge branch 'for-next/mci'
Conflicts: arch/arm/boards/tqma53/board.c
This commit is contained in:
commit
d3c96d6522
|
@ -42,5 +42,7 @@ struct esdhc_platform_data {
|
||||||
enum cd_types cd_type;
|
enum cd_types cd_type;
|
||||||
unsigned caps;
|
unsigned caps;
|
||||||
char *devname;
|
char *devname;
|
||||||
|
unsigned dsr_val;
|
||||||
|
int use_dsr;
|
||||||
};
|
};
|
||||||
#endif /* __ASM_ARCH_IMX_ESDHC_H */
|
#endif /* __ASM_ARCH_IMX_ESDHC_H */
|
||||||
|
|
|
@ -582,6 +582,10 @@ static int fsl_esdhc_probe(struct device_d *dev)
|
||||||
if (host->mci.f_min < 200000)
|
if (host->mci.f_min < 200000)
|
||||||
host->mci.f_min = 200000;
|
host->mci.f_min = 200000;
|
||||||
host->mci.f_max = rate;
|
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);
|
mci_of_parse(&host->mci);
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,20 @@ static void mci_setup_cmd(struct mci_cmd *p, unsigned cmd, unsigned arg, unsigne
|
||||||
p->resp_type = response;
|
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
|
* Setup SD/MMC card's blocklength to be used for future transmitts
|
||||||
* @param mci_dev MCI instance
|
* @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)
|
static void mci_detect_version_from_csd(struct mci *mci)
|
||||||
{
|
{
|
||||||
int version;
|
int version;
|
||||||
char *vstr;
|
|
||||||
|
|
||||||
if (mci->version == MMC_VERSION_UNKNOWN) {
|
if (mci->version == MMC_VERSION_UNKNOWN) {
|
||||||
/* the version is coded in the bits 127:126 (left aligned) */
|
/* 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) {
|
switch (version) {
|
||||||
case 0:
|
case 0:
|
||||||
vstr = "1.2";
|
|
||||||
mci->version = MMC_VERSION_1_2;
|
mci->version = MMC_VERSION_1_2;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
vstr = "1.4";
|
|
||||||
mci->version = MMC_VERSION_1_4;
|
mci->version = MMC_VERSION_1_4;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
vstr = "2.2";
|
|
||||||
mci->version = MMC_VERSION_2_2;
|
mci->version = MMC_VERSION_2_2;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
vstr = "3.0";
|
|
||||||
mci->version = MMC_VERSION_3;
|
mci->version = MMC_VERSION_3;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
vstr = "4.0";
|
|
||||||
mci->version = MMC_VERSION_4;
|
mci->version = MMC_VERSION_4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
vstr = "unknown, fallback to 1.2";
|
printf("unknown card version, fallback to 1.02\n");
|
||||||
mci->version = MMC_VERSION_1_2;
|
mci->version = MMC_VERSION_1_2;
|
||||||
break;
|
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));
|
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)
|
static int mmc_compare_ext_csds(struct mci *mci, unsigned bus_width)
|
||||||
{
|
{
|
||||||
u8 *bw_ext_csd;
|
u8 *bw_ext_csd;
|
||||||
|
@ -1058,6 +1100,7 @@ static int mci_startup(struct mci *mci)
|
||||||
mci_detect_version_from_csd(mci);
|
mci_detect_version_from_csd(mci);
|
||||||
mci_extract_max_tran_speed_from_csd(mci);
|
mci_extract_max_tran_speed_from_csd(mci);
|
||||||
mci_extract_block_lengths_from_csd(mci);
|
mci_extract_block_lengths_from_csd(mci);
|
||||||
|
mci_extract_card_dsr_imp_from_csd(mci);
|
||||||
|
|
||||||
/* sanitiy? */
|
/* sanitiy? */
|
||||||
if (mci->read_bl_len > SECTOR_SIZE) {
|
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",
|
dev_dbg(&mci->dev, "Read block length: %u, Write block length: %u\n",
|
||||||
mci->read_bl_len, mci->write_bl_len);
|
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 */
|
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");
|
dev_dbg(&mci->dev, "Select the card, and put it into Transfer Mode\n");
|
||||||
/* Select the card, and put it into Transfer Mode */
|
/* Select the card, and put it into Transfer Mode */
|
||||||
|
@ -1093,6 +1139,9 @@ static int mci_startup(struct mci *mci)
|
||||||
if (err)
|
if (err)
|
||||||
return 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);
|
mci_extract_card_capacity_from_csd(mci);
|
||||||
|
|
||||||
if (IS_SD(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)
|
static unsigned extract_mtd_year(struct mci *mci)
|
||||||
{
|
{
|
||||||
|
unsigned year;
|
||||||
if (IS_SD(mci))
|
if (IS_SD(mci))
|
||||||
return UNSTUFF_BITS(mci->cid, 12, 8) + 2000;
|
year = UNSTUFF_BITS(mci->cid, 12, 8) + 2000;
|
||||||
else
|
else if (mci->version < MMC_VERSION_4_41)
|
||||||
return UNSTUFF_BITS(mci->cid, 8, 4) + 1997;
|
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)
|
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);
|
(mci->version >> 4) & 0xf, mci->version & 0xf);
|
||||||
} else {
|
} else {
|
||||||
printf(" Attached is an SD Card (Version: %u.%u)\n",
|
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));
|
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;
|
struct device_node *np;
|
||||||
u32 bus_width;
|
u32 bus_width;
|
||||||
|
u32 dsr_val;
|
||||||
|
|
||||||
if (!IS_ENABLED(CONFIG_OFDEVICE))
|
if (!IS_ENABLED(CONFIG_OFDEVICE))
|
||||||
return;
|
return;
|
||||||
|
@ -1751,4 +1808,11 @@ void mci_of_parse(struct mci_host *host)
|
||||||
|
|
||||||
/* f_max is obtained from the optional "max-frequency" property */
|
/* f_max is obtained from the optional "max-frequency" property */
|
||||||
of_property_read_u32(np, "max-frequency", &host->f_max);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,18 +31,23 @@
|
||||||
|
|
||||||
/* Firmware revisions for SD cards */
|
/* Firmware revisions for SD cards */
|
||||||
#define SD_VERSION_SD 0x20000
|
#define SD_VERSION_SD 0x20000
|
||||||
#define SD_VERSION_2 (SD_VERSION_SD | 0x20)
|
#define SD_VERSION_2 (SD_VERSION_SD | 0x200)
|
||||||
#define SD_VERSION_1_0 (SD_VERSION_SD | 0x10)
|
#define SD_VERSION_1_0 (SD_VERSION_SD | 0x100)
|
||||||
#define SD_VERSION_1_10 (SD_VERSION_SD | 0x1a)
|
#define SD_VERSION_1_10 (SD_VERSION_SD | 0x10a)
|
||||||
|
|
||||||
/* Firmware revisions for MMC cards */
|
/* Firmware revisions for MMC cards */
|
||||||
#define MMC_VERSION_MMC 0x10000
|
#define MMC_VERSION_MMC 0x10000
|
||||||
#define MMC_VERSION_UNKNOWN (MMC_VERSION_MMC)
|
#define MMC_VERSION_UNKNOWN (MMC_VERSION_MMC)
|
||||||
#define MMC_VERSION_1_2 (MMC_VERSION_MMC | 0x12)
|
#define MMC_VERSION_1_2 (MMC_VERSION_MMC | 0x102)
|
||||||
#define MMC_VERSION_1_4 (MMC_VERSION_MMC | 0x14)
|
#define MMC_VERSION_1_4 (MMC_VERSION_MMC | 0x104)
|
||||||
#define MMC_VERSION_2_2 (MMC_VERSION_MMC | 0x22)
|
#define MMC_VERSION_2_2 (MMC_VERSION_MMC | 0x202)
|
||||||
#define MMC_VERSION_3 (MMC_VERSION_MMC | 0x30)
|
#define MMC_VERSION_3 (MMC_VERSION_MMC | 0x300)
|
||||||
#define MMC_VERSION_4 (MMC_VERSION_MMC | 0x40)
|
#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_SPI (1 << 0)
|
||||||
#define MMC_CAP_4_BIT_DATA (1 << 1)
|
#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 clock; /**< Current clock used to talk to the card */
|
||||||
unsigned bus_width; /**< used data bus width to the card */
|
unsigned bus_width; /**< used data bus width to the card */
|
||||||
unsigned max_req_size;
|
unsigned max_req_size;
|
||||||
|
unsigned dsr_val; /**< optional dsr value */
|
||||||
|
int use_dsr; /**< optional dsr usage flag */
|
||||||
|
|
||||||
/** init the host interface */
|
/** init the host interface */
|
||||||
int (*init)(struct mci_host*, struct device_d*);
|
int (*init)(struct mci_host*, struct device_d*);
|
||||||
|
@ -344,6 +351,7 @@ struct mci {
|
||||||
unsigned write_bl_len;
|
unsigned write_bl_len;
|
||||||
uint64_t capacity; /**< Card's data capacity in bytes */
|
uint64_t capacity; /**< Card's data capacity in bytes */
|
||||||
int ready_for_use; /** true if already probed */
|
int ready_for_use; /** true if already probed */
|
||||||
|
int dsr_imp; /**< DSR implementation state from CSD */
|
||||||
char *ext_csd;
|
char *ext_csd;
|
||||||
int probe;
|
int probe;
|
||||||
struct param_d *param_probe;
|
struct param_d *param_probe;
|
||||||
|
|
Loading…
Reference in New Issue