__pm_wakeup_event(host->ws, 5000);
host->detect_change = 1;
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+ if (!(host->caps2 & MMC_CAP2_NO_MMC)) {
+ mmc_rescan(&host->detect.work);
+ return;
+ }
+#endif
+
mmc_schedule_delayed_work(&host->detect, delay);
}
return 0;
}
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+ if (host->ops->encrypt_config)
+ host->ops->encrypt_config(host, 0);
+#endif
+
+
/* Order's important: probe SDIO, then SD, then MMC */
if (!(host->caps2 & MMC_CAP2_NO_SDIO))
if (!mmc_attach_sdio(host))
if (!mmc_attach_mmc(host))
return 0;
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+ if (host->ops->encrypt_config)
+ host->ops->encrypt_config(host, 1);
+#endif
+
+
out:
mmc_power_off(host);
return -EIO;
}
mmc_gpiod_request_cd_irq(host);
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+ if (host->caps2 & MMC_CAP2_DISABLE_PROBE_SCAN)
+ return;
+#endif
_mmc_detect_change(host, 0, false);
}
static int _mmc_resume(struct mmc_host *host)
{
int err = 0;
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+ int retry = 3;
+#endif
mmc_claim_host(host);
if (!mmc_card_suspended(host->card))
goto out;
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+retry_resume:
+#endif
mmc_power_up(host, host->card->ocr);
err = mmc_init_card(host, host->card->ocr, host->card);
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+ if (err && retry--) {
+ pr_err("%s: try to retry resume, err:%d\n",
+ mmc_hostname(host), err);
+ mmc_power_off(host);
+ goto retry_resume;
+ }
+#endif
mmc_card_clr_suspended(host->card);
out:
u32 rocr = 0;
bool v18_fixup_failed = false;
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+ u8 tuning_fail = 0;
+#endif
+
+
WARN_ON(!host->claimed);
retry:
err = mmc_sd_get_cid(host, ocr, cid, &rocr);
goto cont;
}
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+ if (tuning_fail)
+ card->sw_caps.sd3_bus_mode &= ~SD_MODE_UHS_SDR104;
+#endif
+
/* Initialization sequence for UHS-I cards */
if (rocr & SD_ROCR_S18A && mmc_host_uhs(host)) {
err = mmc_sd_init_uhs_card(card);
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+ if (err && err == -EIO) {
+ mmc_power_off(host);
+ mmc_power_up(host, host->ocr_avail);
+ tuning_fail = 1;
+ goto retry;
+ }
+#endif
+
if (err)
goto free_card;
} else {
static int mmc_sd_hw_reset(struct mmc_host *host)
{
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+ int ret;
+ int sdr104;
+#endif
+
mmc_power_cycle(host, host->card->ocr);
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+ /* if all selected delaycode have crc, reset to DDR50 */
+ sdr104 = host->caps & MMC_CAP_UHS_SDR104;
+ if (sdr104)
+ host->caps &= ~MMC_CAP_UHS_SDR104;
+ ret = mmc_sd_init_card(host, host->card->ocr, host->card);
+ if (sdr104)
+ host->caps |= MMC_CAP_UHS_SDR104;
+ return ret;
+#else
return mmc_sd_init_card(host, host->card->ocr, host->card);
+#endif
}
static const struct mmc_bus_ops mmc_sd_ops = {
return !(present_state & SDHCI_DATA_0_LVL_MASK);
}
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+static void sdhci_encrypt_config(struct mmc_host *mmc, unsigned int enc_flag)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+
+ if (host->ops->set_encrypt_feature)
+ host->ops->set_encrypt_feature(host, enc_flag);
+}
+#endif
+
static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct sdhci_host *host = mmc_priv(mmc);
.execute_tuning = sdhci_execute_tuning,
.card_event = sdhci_card_event,
.card_busy = sdhci_card_busy,
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+ .encrypt_config = sdhci_encrypt_config,
+#endif
};
/*****************************************************************************\
/* Issue CMD and DATA reset together */
#define SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER (1<<19)
+
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+/* Support SDH controller on FPGA */
+#define SDHCI_QUIRK2_SUPPORT_PHY_BYPASS (1<<25)
+/* Disable scan card at probe phase */
+#define SDHCI_QUIRK2_DISABLE_PROBE_CDSCAN (1<<26)
+/* Need to set IO capability by SOC part register */
+#define SDHCI_QUIRK2_SET_AIB_MMC (1<<27)
+/* Controller not support phy module */
+#define SDHCI_QUIRK2_BROKEN_PHY_MODULE (1<<28)
+/* Controller support encrypt module */
+#define SDHCI_QUIRK2_SUPPORT_ENCRYPT (1<<29)
+#endif
+
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
phys_addr_t mapbase; /* physical address base */
void (*request_done)(struct sdhci_host *host,
struct mmc_request *mrq);
void (*dump_vendor_regs)(struct sdhci_host *host);
+#ifdef CONFIG_ARCH_SPACEMIT_K1X
+ void (*set_encrypt_feature)(struct sdhci_host *host, unsigned int enc_flag);
+#endif
};
#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS