forked from Minki/linux
ead49373d2
In the SD specification v7.10 the SD express card has been added. This new type of removable SD card, can be managed via a PCIe/NVMe based interface, while also allowing backwards compatibility towards the legacy SD interface. To keep the backwards compatibility, it's required to start the initialization through the legacy SD interface. If it turns out that the mmc host and the SD card, both supports the PCIe/NVMe interface, then a switch should be allowed. Therefore, let's introduce some basic support for this type of SD cards to the mmc core. The mmc host, should set MMC_CAP2_SD_EXP if it supports this interface and MMC_CAP2_SD_EXP_1_2V, if also 1.2V is supported, as to inform the core about it. To deal with the switch to the PCIe/NVMe interface, the mmc host is required to implement a new host ops, ->init_sd_express(). Based on the initial communication between the host and the card, host->ios.timing is set to either MMC_TIMING_SD_EXP or MMC_TIMING_SD_EXP_1_2V, depending on if 1.2V is supported or not. In this way, the mmc host can check these values in its ->init_sd_express() ops, to know how to proceed with the handover. Note that, to manage card insert/removal, the mmc core sticks with using the ->get_cd() callback, which means it's the host's responsibility to make sure it provides valid data, even if the card may be managed by PCIe/NVMe at the moment. As long as the card seems to be present, the mmc core keeps the card powered on. Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Christoph Hellwig <hch@lst.de> Cc: Rui Feng <rui_feng@realsil.com.cn> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Link: https://lore.kernel.org/r/1603936636-3126-1-git-send-email-rui_feng@realsil.com.cn
88 lines
2.0 KiB
C
88 lines
2.0 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* linux/drivers/mmc/core/host.h
|
|
*
|
|
* Copyright (C) 2003 Russell King, All Rights Reserved.
|
|
* Copyright 2007 Pierre Ossman
|
|
*/
|
|
#ifndef _MMC_CORE_HOST_H
|
|
#define _MMC_CORE_HOST_H
|
|
|
|
#include <linux/mmc/host.h>
|
|
|
|
int mmc_register_host_class(void);
|
|
void mmc_unregister_host_class(void);
|
|
|
|
void mmc_retune_enable(struct mmc_host *host);
|
|
void mmc_retune_disable(struct mmc_host *host);
|
|
void mmc_retune_hold(struct mmc_host *host);
|
|
void mmc_retune_release(struct mmc_host *host);
|
|
int mmc_retune(struct mmc_host *host);
|
|
void mmc_retune_pause(struct mmc_host *host);
|
|
void mmc_retune_unpause(struct mmc_host *host);
|
|
|
|
static inline void mmc_retune_hold_now(struct mmc_host *host)
|
|
{
|
|
host->retune_now = 0;
|
|
host->hold_retune += 1;
|
|
}
|
|
|
|
static inline void mmc_retune_recheck(struct mmc_host *host)
|
|
{
|
|
if (host->hold_retune <= 1)
|
|
host->retune_now = 1;
|
|
}
|
|
|
|
static inline int mmc_host_cmd23(struct mmc_host *host)
|
|
{
|
|
return host->caps & MMC_CAP_CMD23;
|
|
}
|
|
|
|
static inline bool mmc_host_done_complete(struct mmc_host *host)
|
|
{
|
|
return host->caps & MMC_CAP_DONE_COMPLETE;
|
|
}
|
|
|
|
static inline int mmc_boot_partition_access(struct mmc_host *host)
|
|
{
|
|
return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC);
|
|
}
|
|
|
|
static inline int mmc_host_uhs(struct mmc_host *host)
|
|
{
|
|
return host->caps &
|
|
(MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
|
|
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
|
|
MMC_CAP_UHS_DDR50) &&
|
|
host->caps & MMC_CAP_4_BIT_DATA;
|
|
}
|
|
|
|
static inline bool mmc_card_hs200(struct mmc_card *card)
|
|
{
|
|
return card->host->ios.timing == MMC_TIMING_MMC_HS200;
|
|
}
|
|
|
|
static inline bool mmc_card_ddr52(struct mmc_card *card)
|
|
{
|
|
return card->host->ios.timing == MMC_TIMING_MMC_DDR52;
|
|
}
|
|
|
|
static inline bool mmc_card_hs400(struct mmc_card *card)
|
|
{
|
|
return card->host->ios.timing == MMC_TIMING_MMC_HS400;
|
|
}
|
|
|
|
static inline bool mmc_card_hs400es(struct mmc_card *card)
|
|
{
|
|
return card->host->ios.enhanced_strobe;
|
|
}
|
|
|
|
static inline bool mmc_card_sd_express(struct mmc_host *host)
|
|
{
|
|
return host->ios.timing == MMC_TIMING_SD_EXP ||
|
|
host->ios.timing == MMC_TIMING_SD_EXP_1_2V;
|
|
}
|
|
|
|
#endif
|
|
|