Commit 0e77816e authored by Linus Torvalds's avatar Linus Torvalds

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
parents bfb76444 265984b3
......@@ -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 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment