aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMugunthan V N2017-01-31 06:26:30 -0600
committerKishon Vijay Abraham I2017-06-15 10:10:35 -0500
commit054db19bbf89e1f581d58e9f6e5526be04aca452 (patch)
tree9effd4fb35290be94c570731cc2231f3793b27b3
parent42a6c5565221305949aa51bdef625d719bbd8eeb (diff)
downloadlinux-phy-054db19bbf89e1f581d58e9f6e5526be04aca452.tar.gz
linux-phy-054db19bbf89e1f581d58e9f6e5526be04aca452.tar.xz
linux-phy-054db19bbf89e1f581d58e9f6e5526be04aca452.zip
mmc: host: omap_hsmmc: Add software timer when timeout greater than hardware capablility
DRA7 Errata No i834: When using high speed HS200 and SDR104 cards, the functional clock for MMC module will be 192MHz. At this frequency, the maximum obtainable timeout (DTO =0xE) in hardware is (1/192MHz)*2^27 = 700ms. Commands taking longer than 700ms will be affected by this small window frame and will be timing out frequently even without a genune timeout from the card. Workarround for this errata is use a software timer instead of hardware timer to provide the delay requested by the upper layer So adding a software timer as a work around for the errata. Instead of using software timeout only for larger delays requested when using HS200/SDR104 cards which results in hardware and software timer race conditions, so move all the timeout request to use software timer when HS200/SDR104 card is connected and use hardware timer when other type cards are connected. Also start the software timer after queueing to DMA to ensure we are more likely to expire within correct limits. To be ever more sure that we won't expire this soft timer too early, we're adding a 1000000ns slack to the data timeout requested by the upper layer. [rk@ti.com: fix compiler warning in sw timeout function and use sw timeout for busy timeout] Signed-off-by: Ravikumar Kattekola <rk@ti.com> Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com> [kishon@ti.com: Fix the timeout value to account for the entire transfer to complete here.] Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
-rw-r--r--drivers/mmc/host/omap_hsmmc.c126
1 files changed, 109 insertions, 17 deletions
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 4edcaa907f9f..c7ca9d68bc24 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -185,6 +185,11 @@
185#define PSTATE_DLEV (0xF << 20) 185#define PSTATE_DLEV (0xF << 20)
186#define PSTATE_DLEV_DAT0 (0x1 << 20) 186#define PSTATE_DLEV_DAT0 (0x1 << 20)
187 187
188#define MMC_BLOCK_TRANSFER_TIME_NS(blksz, bus_width, freq) \
189 ((unsigned long long) \
190 (2 * (((blksz) * NSEC_PER_SEC * \
191 (8 / (bus_width))) / (freq))))
192
188/* 193/*
189 * One controller can have multiple slots, like on some omap boards using 194 * One controller can have multiple slots, like on some omap boards using
190 * omap.c controller driver. Luckily this is not currently done on any known 195 * omap.c controller driver. Luckily this is not currently done on any known
@@ -250,6 +255,8 @@ struct omap_hsmmc_host {
250 struct omap_hsmmc_platform_data *pdata; 255 struct omap_hsmmc_platform_data *pdata;
251 256
252 bool is_tuning; 257 bool is_tuning;
258 struct timer_list timer;
259 unsigned long long data_timeout;
253 260
254 /* return MMC cover switch state, can be NULL if not supported. 261 /* return MMC cover switch state, can be NULL if not supported.
255 * 262 *
@@ -631,8 +638,8 @@ static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host,
631 if (host->use_dma) 638 if (host->use_dma)
632 irq_mask &= ~(BRR_EN | BWR_EN); 639 irq_mask &= ~(BRR_EN | BWR_EN);
633 640
634 /* Disable timeout for erases */ 641 /* Disable timeout for erases or when using software timeout */
635 if (cmd->opcode == MMC_ERASE) 642 if (cmd && (cmd->opcode == MMC_ERASE || host->data_timeout))
636 irq_mask &= ~DTO_EN; 643 irq_mask &= ~DTO_EN;
637 644
638 if (host->flags & CLKEXTFREE_ENABLED) 645 if (host->flags & CLKEXTFREE_ENABLED)
@@ -1239,8 +1246,16 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status)
1239 } 1246 }
1240 1247
1241 OMAP_HSMMC_WRITE(host->base, STAT, status); 1248 OMAP_HSMMC_WRITE(host->base, STAT, status);
1242 if (end_cmd || ((status & CC_EN) && host->cmd)) 1249 if (end_cmd || ((status & CC_EN) && host->cmd)) {
1243 omap_hsmmc_cmd_done(host, host->cmd); 1250 omap_hsmmc_cmd_done(host, host->cmd);
1251 if (host->data_timeout) {
1252 unsigned long timeout;
1253
1254 timeout = jiffies +
1255 nsecs_to_jiffies(host->data_timeout);
1256 mod_timer(&host->timer, timeout);
1257 }
1258 }
1244 if ((end_trans || (status & TC_EN)) && host->mrq) 1259 if ((end_trans || (status & TC_EN)) && host->mrq)
1245 omap_hsmmc_xfer_done(host, data); 1260 omap_hsmmc_xfer_done(host, data);
1246} 1261}
@@ -1254,7 +1269,19 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id)
1254 int status; 1269 int status;
1255 1270
1256 status = OMAP_HSMMC_READ(host->base, STAT); 1271 status = OMAP_HSMMC_READ(host->base, STAT);
1272
1257 while (status & (INT_EN_MASK | CIRQ_EN)) { 1273 while (status & (INT_EN_MASK | CIRQ_EN)) {
1274 /*
1275 * During a successful bulk data transfer command-completion
1276 * interrupt and transfer-completion interrupt will be
1277 * generated, but software-timeout timer should be deleted
1278 * only on non-cc interrupts (transfer complete or error)
1279 */
1280 if (host->data_timeout && (status & (~CC_EN))) {
1281 del_timer(&host->timer);
1282 host->data_timeout = 0;
1283 }
1284
1258 if (host->req_in_progress) 1285 if (host->req_in_progress)
1259 omap_hsmmc_do_irq(host, status); 1286 omap_hsmmc_do_irq(host, status);
1260 1287
@@ -1268,6 +1295,25 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id)
1268 return IRQ_HANDLED; 1295 return IRQ_HANDLED;
1269} 1296}
1270 1297
1298static void omap_hsmmc_soft_timeout(unsigned long data)
1299{
1300 struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)data;
1301 bool end_trans = false;
1302
1303 omap_hsmmc_disable_irq(host);
1304 if (host->data || host->response_busy) {
1305 host->response_busy = 0;
1306 end_trans = true;
1307 }
1308
1309 hsmmc_command_incomplete(host, -ETIMEDOUT, 0);
1310 if (end_trans && host->mrq)
1311 omap_hsmmc_xfer_done(host, host->data);
1312 else if (host->cmd)
1313 omap_hsmmc_cmd_done(host, host->cmd);
1314 host->data_timeout = 0;
1315}
1316
1271static void set_sd_bus_power(struct omap_hsmmc_host *host) 1317static void set_sd_bus_power(struct omap_hsmmc_host *host)
1272{ 1318{
1273 unsigned long i; 1319 unsigned long i;
@@ -1462,6 +1508,9 @@ static void set_data_timeout(struct omap_hsmmc_host *host,
1462 unsigned long long timeout = timeout_ns; 1508 unsigned long long timeout = timeout_ns;
1463 unsigned int cycle_ns; 1509 unsigned int cycle_ns;
1464 uint32_t reg, clkd, dto = 0; 1510 uint32_t reg, clkd, dto = 0;
1511 struct mmc_ios *ios = &host->mmc->ios;
1512 struct mmc_data *data = host->mrq->data;
1513 struct mmc_command *cmd = host->mrq->cmd;
1465 1514
1466 reg = OMAP_HSMMC_READ(host->base, SYSCTL); 1515 reg = OMAP_HSMMC_READ(host->base, SYSCTL);
1467 clkd = (reg & CLKD_MASK) >> CLKD_SHIFT; 1516 clkd = (reg & CLKD_MASK) >> CLKD_SHIFT;
@@ -1471,23 +1520,60 @@ static void set_data_timeout(struct omap_hsmmc_host *host,
1471 cycle_ns = 1000000000 / (host->clk_rate / clkd); 1520 cycle_ns = 1000000000 / (host->clk_rate / clkd);
1472 do_div(timeout, cycle_ns); 1521 do_div(timeout, cycle_ns);
1473 timeout += timeout_clks; 1522 timeout += timeout_clks;
1474 if (timeout) { 1523
1475 while ((timeout & 0x80000000) == 0) { 1524 if (!timeout)
1476 dto += 1; 1525 goto out;
1477 timeout <<= 1; 1526
1478 } 1527 while ((timeout & 0x80000000) == 0) {
1479 dto = 31 - dto; 1528 dto += 1;
1480 timeout <<= 1; 1529 timeout <<= 1;
1481 if (timeout && dto) 1530 }
1482 dto += 1; 1531 dto = 31 - dto;
1483 if (dto >= 13) 1532 timeout <<= 1;
1484 dto -= 13; 1533 if (timeout && dto)
1485 else 1534 dto += 1;
1486 dto = 0; 1535 if (dto >= 13)
1487 if (dto > 14) 1536 dto -= 13;
1488 dto = 14; 1537 else
1538 dto = 0;
1539 if (dto > 14) {
1540 /*
1541 * DRA7 Errata No i834: When using high speed HS200 and
1542 * SDR104 cards, the functional clock for MMC module
1543 * will be 192MHz. At this frequency, the maximum
1544 * obtainable timeout (DTO =0xE) in hardware is
1545 * (1/192MHz)*2^27 = 700ms. Commands taking longer than
1546 * 700ms will be affected by this small window frame
1547 * and will be timing out frequently even without a
1548 * genuine timeout from the card. Workaround for
1549 * this errata is use a software timer instead of
1550 * hardware timer to provide the timeout requested
1551 * by the upper layer.
1552 *
1553 * The timeout from the upper layer denotes the delay
1554 * between the end bit of the read command and the
1555 * start bit of the data block and in the case of
1556 * multiple-read operation, they also define the
1557 * typical delay between the end bit of a data
1558 * block and the start bit of next data block.
1559 *
1560 * Calculate the total timeout value for the entire
1561 * transfer to complete from the timeout value given
1562 * by the upper layer.
1563 */
1564 if (data)
1565 host->data_timeout = (data->blocks *
1566 (timeout_ns +
1567 MMC_BLOCK_TRANSFER_TIME_NS(
1568 data->blksz, ios->bus_width,
1569 ios->clock)));
1570 else if (cmd->flags & MMC_RSP_BUSY)
1571 host->data_timeout = timeout_ns;
1572
1573 dto = 14;
1489 } 1574 }
1490 1575
1576out:
1491 reg &= ~DTO_MASK; 1577 reg &= ~DTO_MASK;
1492 reg |= dto << DTO_SHIFT; 1578 reg |= dto << DTO_SHIFT;
1493 OMAP_HSMMC_WRITE(host->base, SYSCTL, reg); 1579 OMAP_HSMMC_WRITE(host->base, SYSCTL, reg);
@@ -2347,6 +2433,8 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
2347 mmc->ops = &omap_hsmmc_ops; 2433 mmc->ops = &omap_hsmmc_ops;
2348 2434
2349 spin_lock_init(&host->irq_lock); 2435 spin_lock_init(&host->irq_lock);
2436 setup_timer(&host->timer, omap_hsmmc_soft_timeout,
2437 (unsigned long)host);
2350 2438
2351 host->fclk = devm_clk_get(&pdev->dev, "fck"); 2439 host->fclk = devm_clk_get(&pdev->dev, "fck");
2352 if (IS_ERR(host->fclk)) { 2440 if (IS_ERR(host->fclk)) {
@@ -2511,6 +2599,8 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
2511 dma_release_channel(host->tx_chan); 2599 dma_release_channel(host->tx_chan);
2512 dma_release_channel(host->rx_chan); 2600 dma_release_channel(host->rx_chan);
2513 2601
2602 del_timer_sync(&host->timer);
2603
2514 pm_runtime_dont_use_autosuspend(host->dev); 2604 pm_runtime_dont_use_autosuspend(host->dev);
2515 pm_runtime_put_sync(host->dev); 2605 pm_runtime_put_sync(host->dev);
2516 pm_runtime_disable(host->dev); 2606 pm_runtime_disable(host->dev);
@@ -2544,6 +2634,8 @@ static int omap_hsmmc_suspend(struct device *dev)
2544 if (host->dbclk) 2634 if (host->dbclk)
2545 clk_disable_unprepare(host->dbclk); 2635 clk_disable_unprepare(host->dbclk);
2546 2636
2637 del_timer_sync(&host->timer);
2638
2547 pm_runtime_put_sync(host->dev); 2639 pm_runtime_put_sync(host->dev);
2548 return 0; 2640 return 0;
2549} 2641}