mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
MMC core:
- Fixup RPMB requests to use mrq->sbc when sending CMD23 MMC host: - omap: Fix broken MMC/SD on OMAP15XX/OMAP5910/OMAP310 - sdhci-omap: Fix DCRC error handling during tuning - sdhci: Fixup the timeout check window for clock and reset -----BEGIN PGP SIGNATURE----- iQJLBAABCgA1FiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAlwSOjAXHHVsZi5oYW5z c29uQGxpbmFyby5vcmcACgkQ/iaEJXNYjCkexA//cw/KotpQQpIirpmVvvnB52aR eephJ6CsoFC6Mqdmjto9i4hO4bwsDr0S8RQBjF+rpcGzN2lo3Kn6rongKxWd5Y++ UZkNdY/t8rGe/bumbaQgvMNnQ7RcwknlL36Xn2sN+hcoqY4/8P/3eF4+ysc4i4Gy PG6AHXVNotCmQwwCElAmhKoQN2JCMRZyUlMkgl/yXqLljhEQJ0jzWHicFFsRMF4t teCV3CGazffYopipiQUeRNKUbCTaF8UFoybgONnyVXFy9gmzzAAbb6behRbh2U/s XNqopa2R3wwxXep2TrwUDYMrDFl1ibRnuYi0VYz0VZRyA1vdEz8XKB3QQaQf03d2 yzjWUWd4YI0RZMrdhaOIyvVkbk9//2JzrCHen1wnhU8AFInpJdcwN0NKcVCUJXfb 5f2fB1GO9lDogW0n+z57+Hsux9wWWcLcfrY5g454qlySou/jmvfhH0onhQOH4aTs oJcU7vDsZQHftQYfol2e8K/5m3KKRKVRCDLzw0RRQbplC04r/5afuL3dA1YEI8/Y ZTAgd0rOXvOY+oW4q0a8CbEnknk9MoXUd41/LkbG8eJWliStOsV0PJZzmgDcIgPH EB3LyZRccJwKzSMtLLktx/iTm4grVjFABnQxlf80twoJjjnlcoNaBYHfr3Zc9BTf 7E7AXxdUUwMn5qWhOxQ= =wS1m -----END PGP SIGNATURE----- Merge tag 'mmc-v4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc Pull mmc fixes from Ulf Hansson: "MMC core: - Fixup RPMB requests to use mrq->sbc when sending CMD23 MMC host: - omap: Fix broken MMC/SD on OMAP15XX/OMAP5910/OMAP310 - sdhci-omap: Fix DCRC error handling during tuning - sdhci: Fixup the timeout check window for clock and reset" * tag 'mmc-v4.20-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: mmc: sdhci: fix the timeout check window for clock and reset mmc: sdhci-omap: Fix DCRC error handling during tuning MMC: OMAP: fix broken MMC on OMAP15XX/OMAP5910/OMAP310 mmc: core: use mrq->sbc when sending CMD23 for RPMB
This commit is contained in:
commit
e861e11c59
@ -472,7 +472,7 @@ out:
|
||||
static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
|
||||
struct mmc_blk_ioc_data *idata)
|
||||
{
|
||||
struct mmc_command cmd = {};
|
||||
struct mmc_command cmd = {}, sbc = {};
|
||||
struct mmc_data data = {};
|
||||
struct mmc_request mrq = {};
|
||||
struct scatterlist sg;
|
||||
@ -550,10 +550,15 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
|
||||
}
|
||||
|
||||
if (idata->rpmb) {
|
||||
err = mmc_set_blockcount(card, data.blocks,
|
||||
idata->ic.write_flag & (1 << 31));
|
||||
if (err)
|
||||
return err;
|
||||
sbc.opcode = MMC_SET_BLOCK_COUNT;
|
||||
/*
|
||||
* We don't do any blockcount validation because the max size
|
||||
* may be increased by a future standard. We just copy the
|
||||
* 'Reliable Write' bit here.
|
||||
*/
|
||||
sbc.arg = data.blocks | (idata->ic.write_flag & BIT(31));
|
||||
sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
|
||||
mrq.sbc = &sbc;
|
||||
}
|
||||
|
||||
if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) &&
|
||||
|
@ -104,6 +104,7 @@ struct mmc_omap_slot {
|
||||
unsigned int vdd;
|
||||
u16 saved_con;
|
||||
u16 bus_mode;
|
||||
u16 power_mode;
|
||||
unsigned int fclk_freq;
|
||||
|
||||
struct tasklet_struct cover_tasklet;
|
||||
@ -1157,7 +1158,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
struct mmc_omap_slot *slot = mmc_priv(mmc);
|
||||
struct mmc_omap_host *host = slot->host;
|
||||
int i, dsor;
|
||||
int clk_enabled;
|
||||
int clk_enabled, init_stream;
|
||||
|
||||
mmc_omap_select_slot(slot, 0);
|
||||
|
||||
@ -1167,6 +1168,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
slot->vdd = ios->vdd;
|
||||
|
||||
clk_enabled = 0;
|
||||
init_stream = 0;
|
||||
switch (ios->power_mode) {
|
||||
case MMC_POWER_OFF:
|
||||
mmc_omap_set_power(slot, 0, ios->vdd);
|
||||
@ -1174,13 +1176,17 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
case MMC_POWER_UP:
|
||||
/* Cannot touch dsor yet, just power up MMC */
|
||||
mmc_omap_set_power(slot, 1, ios->vdd);
|
||||
slot->power_mode = ios->power_mode;
|
||||
goto exit;
|
||||
case MMC_POWER_ON:
|
||||
mmc_omap_fclk_enable(host, 1);
|
||||
clk_enabled = 1;
|
||||
dsor |= 1 << 11;
|
||||
if (slot->power_mode != MMC_POWER_ON)
|
||||
init_stream = 1;
|
||||
break;
|
||||
}
|
||||
slot->power_mode = ios->power_mode;
|
||||
|
||||
if (slot->bus_mode != ios->bus_mode) {
|
||||
if (slot->pdata->set_bus_mode != NULL)
|
||||
@ -1196,7 +1202,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
for (i = 0; i < 2; i++)
|
||||
OMAP_MMC_WRITE(host, CON, dsor);
|
||||
slot->saved_con = dsor;
|
||||
if (ios->power_mode == MMC_POWER_ON) {
|
||||
if (init_stream) {
|
||||
/* worst case at 400kHz, 80 cycles makes 200 microsecs */
|
||||
int usecs = 250;
|
||||
|
||||
@ -1234,6 +1240,7 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id)
|
||||
slot->host = host;
|
||||
slot->mmc = mmc;
|
||||
slot->id = id;
|
||||
slot->power_mode = MMC_POWER_UNDEFINED;
|
||||
slot->pdata = &host->pdata->slots[id];
|
||||
|
||||
host->slots[id] = slot;
|
||||
|
@ -288,9 +288,9 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
||||
struct device *dev = omap_host->dev;
|
||||
struct mmc_ios *ios = &mmc->ios;
|
||||
u32 start_window = 0, max_window = 0;
|
||||
bool dcrc_was_enabled = false;
|
||||
u8 cur_match, prev_match = 0;
|
||||
u32 length = 0, max_len = 0;
|
||||
u32 ier = host->ier;
|
||||
u32 phase_delay = 0;
|
||||
int ret = 0;
|
||||
u32 reg;
|
||||
@ -317,9 +317,10 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode)
|
||||
* during the tuning procedure. So disable it during the
|
||||
* tuning procedure.
|
||||
*/
|
||||
ier &= ~SDHCI_INT_DATA_CRC;
|
||||
sdhci_writel(host, ier, SDHCI_INT_ENABLE);
|
||||
sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
|
||||
if (host->ier & SDHCI_INT_DATA_CRC) {
|
||||
host->ier &= ~SDHCI_INT_DATA_CRC;
|
||||
dcrc_was_enabled = true;
|
||||
}
|
||||
|
||||
while (phase_delay <= MAX_PHASE_DELAY) {
|
||||
sdhci_omap_set_dll(omap_host, phase_delay);
|
||||
@ -366,6 +367,9 @@ tuning_error:
|
||||
|
||||
ret:
|
||||
sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
|
||||
/* Reenable forbidden interrupt */
|
||||
if (dcrc_was_enabled)
|
||||
host->ier |= SDHCI_INT_DATA_CRC;
|
||||
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
|
||||
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
|
||||
return ret;
|
||||
|
@ -216,8 +216,12 @@ void sdhci_reset(struct sdhci_host *host, u8 mask)
|
||||
timeout = ktime_add_ms(ktime_get(), 100);
|
||||
|
||||
/* hw clears the bit when it's done */
|
||||
while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
|
||||
if (ktime_after(ktime_get(), timeout)) {
|
||||
while (1) {
|
||||
bool timedout = ktime_after(ktime_get(), timeout);
|
||||
|
||||
if (!(sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask))
|
||||
break;
|
||||
if (timedout) {
|
||||
pr_err("%s: Reset 0x%x never completed.\n",
|
||||
mmc_hostname(host->mmc), (int)mask);
|
||||
sdhci_dumpregs(host);
|
||||
@ -1608,9 +1612,13 @@ void sdhci_enable_clk(struct sdhci_host *host, u16 clk)
|
||||
|
||||
/* Wait max 20 ms */
|
||||
timeout = ktime_add_ms(ktime_get(), 20);
|
||||
while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
|
||||
& SDHCI_CLOCK_INT_STABLE)) {
|
||||
if (ktime_after(ktime_get(), timeout)) {
|
||||
while (1) {
|
||||
bool timedout = ktime_after(ktime_get(), timeout);
|
||||
|
||||
clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
|
||||
if (clk & SDHCI_CLOCK_INT_STABLE)
|
||||
break;
|
||||
if (timedout) {
|
||||
pr_err("%s: Internal clock never stabilised.\n",
|
||||
mmc_hostname(host->mmc));
|
||||
sdhci_dumpregs(host);
|
||||
|
Loading…
Reference in New Issue
Block a user