mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-23 01:40:30 +00:00
MMC core:
- Prevent re-tuning while serving requests for RPMB partitions - Extend timeout for long read time quirk to support more eMMCs MMC host: - sdhci-acpi: Ensure connected devices are powered when probing - sdhci-pci|acpi: Remove unreliable MMC_CAP_BUS_WIDTH_TEST for Intel HWs - dw_mmc: Correct the assigning of max_blk_size - dw_mmc-rockchip: Allow RPMB partitions to be created - dw_mmc-rockchip: Set the drive phase properly -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXRq1wAAoJEP4mhCVzWIwpKa0QAId0gcmR5EF45FHYdNP50TgJ EgJa8xFZiBXC/RZbcDYBOfNVcQ+RqvCs4K5PxJcpleARA7MtCcbwWpKynHG/2cdR xbZbzuuMd4jKS7AO6kC1Rww370XTRhtXAlkO1w/KWvnC79wV86EgIxxl8adBycw7 68JFmjrcDTyBq63G0jHZlUzA8mVxl+k9Jb3lW1+FnsGMCV7R4dOK58rwp3z7ITwl r4sSQGN6STwlav3tLlurNi/7Wd9VfHjbuuwSR9oIc11hRzBNNL+I2Runk/4lfD6q 52S4OYoqPiZrMheYonQ6zVAjm9MVWLAMId6AbJXlx8m42qbq2q2o4gv4csGjKiNr e8ZaHRw8FYRL8A4UewYcewPxJfXkJSV81KNKQYS1jn94zfPspffln73VM1Sbqmu8 tg89C1CYShAS0IcIyKk3XCBocq6JARIF+M7mE3FTZd3yfBd6hBbjUbv9ufKnbsxJ lSG9jISCYaqsoc4SLK/hBEypN68otLKDm7Jl8VcPj351f5NDlj0hv56scqt3HbAk hcPUYtHc5+6vsQ1mIQRC+NmH9qacChq8JfLHej7HB+hSCJZUp35QB0Zr6oTmv4G4 9mUY/J6++9fGQtcWWAyNcVOuZUjGSxiSDm6wgtZMJZDYUFECXDdPEYRatBIMa2Ul 4bbcKYEbqdC8Cn2q5FZn =zHa6 -----END PGP SIGNATURE----- Merge tag 'mmc-v4.7-rc1' of git://git.linaro.org/people/ulf.hansson/mmc Pull MMC fixes from Ulf Hansson: "Here are some mmc fixes intended for v4.7 rc1. They are based on a commit earlier in the merge window and have been tested in linux-next for a while. MMC core: - Prevent re-tuning while serving requests for RPMB partitions - Extend timeout for long read time quirk to support more eMMCs MMC host: - sdhci-acpi: Ensure connected devices are powered when probing - sdhci-pci|acpi: Remove unreliable MMC_CAP_BUS_WIDTH_TEST for Intel HWs - dw_mmc: Correct the assigning of max_blk_size - dw_mmc-rockchip: Allow RPMB partitions to be created - dw_mmc-rockchip: Set the drive phase properly" * tag 'mmc-v4.7-rc1' of git://git.linaro.org/people/ulf.hansson/mmc: mmc: sdhci-acpi: Remove MMC_CAP_BUS_WIDTH_TEST for Intel controllers mmc: sdhci-pci: Remove MMC_CAP_BUS_WIDTH_TEST for Intel controllers mmc: longer timeout for long read time quirk mmc: dw_mmc: rockchip: Set the drive phase properly mmc: dw_mmc: fix the wrong max_blk_size mmc: dw_mmc-rockchip: add MMC_CAP_CMD23 capabilities mmc: sdhci-acpi: Ensure connected devices are powered when probing ACPI / PM: Export acpi_device_fix_up_power() mmc: block: Pause re-tuning while switched to the RPMB partition mmc: block: Always switch back to main area after RPMB access mmc: core: Add a facility to "pause" re-tuning
This commit is contained in:
commit
0e77816e09
@ -319,6 +319,7 @@ int acpi_device_fix_up_power(struct acpi_device *device)
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_device_fix_up_power);
|
||||
|
||||
int acpi_device_update_power(struct acpi_device *device, int *state_p)
|
||||
{
|
||||
|
@ -618,6 +618,10 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
|
||||
|
||||
ioc_err = __mmc_blk_ioctl_cmd(card, md, idata);
|
||||
|
||||
/* Always switch back to main area after RPMB access */
|
||||
if (md->area_type & MMC_BLK_DATA_AREA_RPMB)
|
||||
mmc_blk_part_switch(card, dev_get_drvdata(&card->dev));
|
||||
|
||||
mmc_put_card(card);
|
||||
|
||||
err = mmc_blk_ioctl_copy_to_user(ic_ptr, idata);
|
||||
@ -685,6 +689,10 @@ static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev,
|
||||
for (i = 0; i < num_of_cmds && !ioc_err; i++)
|
||||
ioc_err = __mmc_blk_ioctl_cmd(card, md, idata[i]);
|
||||
|
||||
/* Always switch back to main area after RPMB access */
|
||||
if (md->area_type & MMC_BLK_DATA_AREA_RPMB)
|
||||
mmc_blk_part_switch(card, dev_get_drvdata(&card->dev));
|
||||
|
||||
mmc_put_card(card);
|
||||
|
||||
/* copy to user if data and response */
|
||||
@ -748,16 +756,25 @@ static inline int mmc_blk_part_switch(struct mmc_card *card,
|
||||
if (mmc_card_mmc(card)) {
|
||||
u8 part_config = card->ext_csd.part_config;
|
||||
|
||||
if (md->part_type == EXT_CSD_PART_CONFIG_ACC_RPMB)
|
||||
mmc_retune_pause(card->host);
|
||||
|
||||
part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
|
||||
part_config |= md->part_type;
|
||||
|
||||
ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
||||
EXT_CSD_PART_CONFIG, part_config,
|
||||
card->ext_csd.part_time);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
if (md->part_type == EXT_CSD_PART_CONFIG_ACC_RPMB)
|
||||
mmc_retune_unpause(card->host);
|
||||
return ret;
|
||||
}
|
||||
|
||||
card->ext_csd.part_config = part_config;
|
||||
|
||||
if (main_md->part_curr == EXT_CSD_PART_CONFIG_ACC_RPMB)
|
||||
mmc_retune_unpause(card->host);
|
||||
}
|
||||
|
||||
main_md->part_curr = md->part_type;
|
||||
@ -2519,11 +2536,12 @@ static const struct mmc_fixup blk_fixups[] =
|
||||
MMC_QUIRK_BLK_NO_CMD23),
|
||||
|
||||
/*
|
||||
* Some Micron MMC cards needs longer data read timeout than
|
||||
* indicated in CSD.
|
||||
* Some MMC cards need longer data read timeout than indicated in CSD.
|
||||
*/
|
||||
MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc,
|
||||
MMC_QUIRK_LONG_READ_TIME),
|
||||
MMC_FIXUP("008GE0", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
|
||||
MMC_QUIRK_LONG_READ_TIME),
|
||||
|
||||
/*
|
||||
* On these Samsung MoviNAND parts, performing secure erase or
|
||||
|
@ -875,11 +875,11 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
|
||||
/*
|
||||
* Some cards require longer data read timeout than indicated in CSD.
|
||||
* Address this by setting the read timeout to a "reasonably high"
|
||||
* value. For the cards tested, 300ms has proven enough. If necessary,
|
||||
* value. For the cards tested, 600ms has proven enough. If necessary,
|
||||
* this value can be increased if other problematic cards require this.
|
||||
*/
|
||||
if (mmc_card_long_read_time(card) && data->flags & MMC_DATA_READ) {
|
||||
data->timeout_ns = 300000000;
|
||||
data->timeout_ns = 600000000;
|
||||
data->timeout_clks = 0;
|
||||
}
|
||||
|
||||
|
@ -68,8 +68,32 @@ void mmc_retune_enable(struct mmc_host *host)
|
||||
jiffies + host->retune_period * HZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pause re-tuning for a small set of operations. The pause begins after the
|
||||
* next command and after first doing re-tuning.
|
||||
*/
|
||||
void mmc_retune_pause(struct mmc_host *host)
|
||||
{
|
||||
if (!host->retune_paused) {
|
||||
host->retune_paused = 1;
|
||||
mmc_retune_needed(host);
|
||||
mmc_retune_hold(host);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(mmc_retune_pause);
|
||||
|
||||
void mmc_retune_unpause(struct mmc_host *host)
|
||||
{
|
||||
if (host->retune_paused) {
|
||||
host->retune_paused = 0;
|
||||
mmc_retune_release(host);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(mmc_retune_unpause);
|
||||
|
||||
void mmc_retune_disable(struct mmc_host *host)
|
||||
{
|
||||
mmc_retune_unpause(host);
|
||||
host->can_retune = 0;
|
||||
del_timer_sync(&host->retune_timer);
|
||||
host->retune_now = 0;
|
||||
|
@ -66,6 +66,70 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
|
||||
/* Make sure we use phases which we can enumerate with */
|
||||
if (!IS_ERR(priv->sample_clk))
|
||||
clk_set_phase(priv->sample_clk, priv->default_sample_phase);
|
||||
|
||||
/*
|
||||
* Set the drive phase offset based on speed mode to achieve hold times.
|
||||
*
|
||||
* NOTE: this is _not_ a value that is dynamically tuned and is also
|
||||
* _not_ a value that will vary from board to board. It is a value
|
||||
* that could vary between different SoC models if they had massively
|
||||
* different output clock delays inside their dw_mmc IP block (delay_o),
|
||||
* but since it's OK to overshoot a little we don't need to do complex
|
||||
* calculations and can pick values that will just work for everyone.
|
||||
*
|
||||
* When picking values we'll stick with picking 0/90/180/270 since
|
||||
* those can be made very accurately on all known Rockchip SoCs.
|
||||
*
|
||||
* Note that these values match values from the DesignWare Databook
|
||||
* tables for the most part except for SDR12 and "ID mode". For those
|
||||
* two modes the databook calculations assume a clock in of 50MHz. As
|
||||
* seen above, we always use a clock in rate that is exactly the
|
||||
* card's input clock (times RK3288_CLKGEN_DIV, but that gets divided
|
||||
* back out before the controller sees it).
|
||||
*
|
||||
* From measurement of a single device, it appears that delay_o is
|
||||
* about .5 ns. Since we try to leave a bit of margin, it's expected
|
||||
* that numbers here will be fine even with much larger delay_o
|
||||
* (the 1.4 ns assumed by the DesignWare Databook would result in the
|
||||
* same results, for instance).
|
||||
*/
|
||||
if (!IS_ERR(priv->drv_clk)) {
|
||||
int phase;
|
||||
|
||||
/*
|
||||
* In almost all cases a 90 degree phase offset will provide
|
||||
* sufficient hold times across all valid input clock rates
|
||||
* assuming delay_o is not absurd for a given SoC. We'll use
|
||||
* that as a default.
|
||||
*/
|
||||
phase = 90;
|
||||
|
||||
switch (ios->timing) {
|
||||
case MMC_TIMING_MMC_DDR52:
|
||||
/*
|
||||
* Since clock in rate with MMC_DDR52 is doubled when
|
||||
* bus width is 8 we need to double the phase offset
|
||||
* to get the same timings.
|
||||
*/
|
||||
if (ios->bus_width == MMC_BUS_WIDTH_8)
|
||||
phase = 180;
|
||||
break;
|
||||
case MMC_TIMING_UHS_SDR104:
|
||||
case MMC_TIMING_MMC_HS200:
|
||||
/*
|
||||
* In the case of 150 MHz clock (typical max for
|
||||
* Rockchip SoCs), 90 degree offset will add a delay
|
||||
* of 1.67 ns. That will meet min hold time of .8 ns
|
||||
* as long as clock output delay is < .87 ns. On
|
||||
* SoCs measured this seems to be OK, but it doesn't
|
||||
* hurt to give margin here, so we use 180.
|
||||
*/
|
||||
phase = 180;
|
||||
break;
|
||||
}
|
||||
|
||||
clk_set_phase(priv->drv_clk, phase);
|
||||
}
|
||||
}
|
||||
|
||||
#define NUM_PHASES 360
|
||||
@ -233,10 +297,10 @@ static int dw_mci_rockchip_init(struct dw_mci *host)
|
||||
|
||||
/* Common capabilities of RK3288 SoC */
|
||||
static unsigned long dw_mci_rk3288_dwmmc_caps[4] = {
|
||||
MMC_CAP_ERASE,
|
||||
MMC_CAP_ERASE,
|
||||
MMC_CAP_ERASE,
|
||||
MMC_CAP_ERASE,
|
||||
MMC_CAP_ERASE | MMC_CAP_CMD23,
|
||||
MMC_CAP_ERASE | MMC_CAP_CMD23,
|
||||
MMC_CAP_ERASE | MMC_CAP_CMD23,
|
||||
MMC_CAP_ERASE | MMC_CAP_CMD23,
|
||||
};
|
||||
|
||||
static const struct dw_mci_drv_data rk2928_drv_data = {
|
||||
|
@ -2595,13 +2595,13 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
|
||||
/* Useful defaults if platform data is unset. */
|
||||
if (host->use_dma == TRANS_MODE_IDMAC) {
|
||||
mmc->max_segs = host->ring_size;
|
||||
mmc->max_blk_size = 65536;
|
||||
mmc->max_blk_size = 65535;
|
||||
mmc->max_seg_size = 0x1000;
|
||||
mmc->max_req_size = mmc->max_seg_size * host->ring_size;
|
||||
mmc->max_blk_count = mmc->max_req_size / 512;
|
||||
} else if (host->use_dma == TRANS_MODE_EDMAC) {
|
||||
mmc->max_segs = 64;
|
||||
mmc->max_blk_size = 65536;
|
||||
mmc->max_blk_size = 65535;
|
||||
mmc->max_blk_count = 65535;
|
||||
mmc->max_req_size =
|
||||
mmc->max_blk_size * mmc->max_blk_count;
|
||||
@ -2609,7 +2609,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
|
||||
} else {
|
||||
/* TRANS_MODE_PIO */
|
||||
mmc->max_segs = 64;
|
||||
mmc->max_blk_size = 65536; /* BLKSIZ is 16 bits */
|
||||
mmc->max_blk_size = 65535; /* BLKSIZ is 16 bits */
|
||||
mmc->max_blk_count = 512;
|
||||
mmc->max_req_size = mmc->max_blk_size *
|
||||
mmc->max_blk_count;
|
||||
|
@ -274,7 +274,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = {
|
||||
.chip = &sdhci_acpi_chip_int,
|
||||
.caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
|
||||
MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR |
|
||||
MMC_CAP_BUS_WIDTH_TEST | MMC_CAP_WAIT_WHILE_BUSY,
|
||||
MMC_CAP_WAIT_WHILE_BUSY,
|
||||
.caps2 = MMC_CAP2_HC_ERASE_SZ,
|
||||
.flags = SDHCI_ACPI_RUNTIME_PM,
|
||||
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
|
||||
@ -289,7 +289,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = {
|
||||
SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
|
||||
.quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
|
||||
.caps = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD |
|
||||
MMC_CAP_BUS_WIDTH_TEST | MMC_CAP_WAIT_WHILE_BUSY,
|
||||
MMC_CAP_WAIT_WHILE_BUSY,
|
||||
.flags = SDHCI_ACPI_RUNTIME_PM,
|
||||
.pm_caps = MMC_PM_KEEP_POWER,
|
||||
.probe_slot = sdhci_acpi_sdio_probe_slot,
|
||||
@ -301,7 +301,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = {
|
||||
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
|
||||
.quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON |
|
||||
SDHCI_QUIRK2_STOP_WITH_TC,
|
||||
.caps = MMC_CAP_BUS_WIDTH_TEST | MMC_CAP_WAIT_WHILE_BUSY,
|
||||
.caps = MMC_CAP_WAIT_WHILE_BUSY,
|
||||
.probe_slot = sdhci_acpi_sd_probe_slot,
|
||||
};
|
||||
|
||||
@ -378,7 +378,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
acpi_handle handle = ACPI_HANDLE(dev);
|
||||
struct acpi_device *device;
|
||||
struct acpi_device *device, *child;
|
||||
struct sdhci_acpi_host *c;
|
||||
struct sdhci_host *host;
|
||||
struct resource *iomem;
|
||||
@ -390,6 +390,11 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
|
||||
if (acpi_bus_get_device(handle, &device))
|
||||
return -ENODEV;
|
||||
|
||||
/* Power on the SDHCI controller and its children */
|
||||
acpi_device_fix_up_power(device);
|
||||
list_for_each_entry(child, &device->children, node)
|
||||
acpi_device_fix_up_power(child);
|
||||
|
||||
if (acpi_bus_get_status(device) || !device->status.present)
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -356,7 +356,6 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
|
||||
{
|
||||
slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
|
||||
MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR |
|
||||
MMC_CAP_BUS_WIDTH_TEST |
|
||||
MMC_CAP_WAIT_WHILE_BUSY;
|
||||
slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ;
|
||||
slot->hw_reset = sdhci_pci_int_hw_reset;
|
||||
@ -372,15 +371,13 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
|
||||
static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
|
||||
{
|
||||
slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
|
||||
MMC_CAP_BUS_WIDTH_TEST |
|
||||
MMC_CAP_WAIT_WHILE_BUSY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int byt_sd_probe_slot(struct sdhci_pci_slot *slot)
|
||||
{
|
||||
slot->host->mmc->caps |= MMC_CAP_BUS_WIDTH_TEST |
|
||||
MMC_CAP_WAIT_WHILE_BUSY;
|
||||
slot->host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
|
||||
slot->cd_con_id = NULL;
|
||||
slot->cd_idx = 0;
|
||||
slot->cd_override_level = true;
|
||||
|
@ -329,6 +329,7 @@ struct mmc_host {
|
||||
unsigned int can_retune:1; /* re-tuning can be used */
|
||||
unsigned int doing_retune:1; /* re-tuning in progress */
|
||||
unsigned int retune_now:1; /* do re-tuning at next req */
|
||||
unsigned int retune_paused:1; /* re-tuning is temporarily disabled */
|
||||
|
||||
int rescan_disable; /* disable card detection */
|
||||
int rescan_entered; /* used with nonremovable devices */
|
||||
@ -526,4 +527,7 @@ static inline void mmc_retune_recheck(struct mmc_host *host)
|
||||
host->retune_now = 1;
|
||||
}
|
||||
|
||||
void mmc_retune_pause(struct mmc_host *host);
|
||||
void mmc_retune_unpause(struct mmc_host *host);
|
||||
|
||||
#endif /* LINUX_MMC_HOST_H */
|
||||
|
Loading…
Reference in New Issue
Block a user