| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Synopsys DesignWare Multimedia Card Interface driver |
|---|
| 3 | 4 | * (Based on NXP driver for lpc 31xx) |
|---|
| 4 | 5 | * |
|---|
| 5 | 6 | * Copyright (C) 2009 NXP Semiconductors |
|---|
| 6 | 7 | * Copyright (C) 2009, 2010 Imagination Technologies Ltd. |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 10 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 11 | | - * (at your option) any later version. |
|---|
| 12 | 8 | */ |
|---|
| 13 | 9 | |
|---|
| 14 | 10 | #include <linux/blkdev.h> |
|---|
| .. | .. |
|---|
| 40 | 36 | #include <linux/of.h> |
|---|
| 41 | 37 | #include <linux/of_gpio.h> |
|---|
| 42 | 38 | #include <linux/mmc/slot-gpio.h> |
|---|
| 39 | +#include <linux/soc/rockchip/rk_sdmmc.h> |
|---|
| 43 | 40 | #include <linux/soc/rockchip/rockchip_decompress.h> |
|---|
| 44 | 41 | |
|---|
| 45 | 42 | #include "dw_mmc.h" |
|---|
| .. | .. |
|---|
| 109 | 106 | /* Each descriptor can transfer up to 4KB of data in chained mode */ |
|---|
| 110 | 107 | #define DW_MCI_DESC_DATA_LENGTH 0x1000 |
|---|
| 111 | 108 | |
|---|
| 109 | +#if IS_ENABLED(CONFIG_CPU_RV1106) |
|---|
| 110 | +static spinlock_t *g_sdmmc_ispvicap_lock; |
|---|
| 111 | + |
|---|
| 112 | +void rv1106_sdmmc_get_lock(void) |
|---|
| 113 | +{ |
|---|
| 114 | + if (g_sdmmc_ispvicap_lock) |
|---|
| 115 | + spin_lock(g_sdmmc_ispvicap_lock); |
|---|
| 116 | +} |
|---|
| 117 | +EXPORT_SYMBOL(rv1106_sdmmc_get_lock); |
|---|
| 118 | + |
|---|
| 119 | +void rv1106_sdmmc_put_lock(void) |
|---|
| 120 | +{ |
|---|
| 121 | + if (g_sdmmc_ispvicap_lock) |
|---|
| 122 | + spin_unlock(g_sdmmc_ispvicap_lock); |
|---|
| 123 | +} |
|---|
| 124 | +EXPORT_SYMBOL(rv1106_sdmmc_put_lock); |
|---|
| 125 | +#endif |
|---|
| 126 | + |
|---|
| 127 | +#define RV1106_RAMDON_DATA_SIZE 508 |
|---|
| 128 | + |
|---|
| 112 | 129 | #if defined(CONFIG_DEBUG_FS) |
|---|
| 113 | 130 | static int dw_mci_req_show(struct seq_file *s, void *v) |
|---|
| 114 | 131 | { |
|---|
| .. | .. |
|---|
| 175 | 192 | struct mmc_host *mmc = slot->mmc; |
|---|
| 176 | 193 | struct dw_mci *host = slot->host; |
|---|
| 177 | 194 | struct dentry *root; |
|---|
| 178 | | - struct dentry *node; |
|---|
| 179 | 195 | |
|---|
| 180 | 196 | root = mmc->debugfs_root; |
|---|
| 181 | 197 | if (!root) |
|---|
| 182 | 198 | return; |
|---|
| 183 | 199 | |
|---|
| 184 | | - node = debugfs_create_file("regs", S_IRUSR, root, host, |
|---|
| 185 | | - &dw_mci_regs_fops); |
|---|
| 186 | | - if (!node) |
|---|
| 187 | | - goto err; |
|---|
| 188 | | - |
|---|
| 189 | | - node = debugfs_create_file("req", S_IRUSR, root, slot, |
|---|
| 190 | | - &dw_mci_req_fops); |
|---|
| 191 | | - if (!node) |
|---|
| 192 | | - goto err; |
|---|
| 193 | | - |
|---|
| 194 | | - node = debugfs_create_u32("state", S_IRUSR, root, (u32 *)&host->state); |
|---|
| 195 | | - if (!node) |
|---|
| 196 | | - goto err; |
|---|
| 197 | | - |
|---|
| 198 | | - node = debugfs_create_x32("pending_events", S_IRUSR, root, |
|---|
| 199 | | - (u32 *)&host->pending_events); |
|---|
| 200 | | - if (!node) |
|---|
| 201 | | - goto err; |
|---|
| 202 | | - |
|---|
| 203 | | - node = debugfs_create_x32("completed_events", S_IRUSR, root, |
|---|
| 204 | | - (u32 *)&host->completed_events); |
|---|
| 205 | | - if (!node) |
|---|
| 206 | | - goto err; |
|---|
| 207 | | - |
|---|
| 208 | | - return; |
|---|
| 209 | | - |
|---|
| 210 | | -err: |
|---|
| 211 | | - dev_err(&mmc->class_dev, "failed to initialize debugfs for slot\n"); |
|---|
| 200 | + debugfs_create_file("regs", S_IRUSR, root, host, &dw_mci_regs_fops); |
|---|
| 201 | + debugfs_create_file("req", S_IRUSR, root, slot, &dw_mci_req_fops); |
|---|
| 202 | + debugfs_create_u32("state", S_IRUSR, root, &host->state); |
|---|
| 203 | + debugfs_create_xul("pending_events", S_IRUSR, root, |
|---|
| 204 | + &host->pending_events); |
|---|
| 205 | + debugfs_create_xul("completed_events", S_IRUSR, root, |
|---|
| 206 | + &host->completed_events); |
|---|
| 212 | 207 | } |
|---|
| 213 | 208 | #endif /* defined(CONFIG_DEBUG_FS) */ |
|---|
| 214 | 209 | |
|---|
| .. | .. |
|---|
| 247 | 242 | * expected. |
|---|
| 248 | 243 | */ |
|---|
| 249 | 244 | #ifdef CONFIG_ROCKCHIP_THUNDER_BOOT_MMC |
|---|
| 250 | | - if (host->slot->mmc->restrict_caps & RESTRICT_CARD_TYPE_EMMC) |
|---|
| 245 | + if (host->slot->mmc->caps2 & MMC_CAP2_NO_SD && |
|---|
| 246 | + host->slot->mmc->caps2 & MMC_CAP2_NO_SDIO) |
|---|
| 251 | 247 | delay = 0; |
|---|
| 252 | 248 | #endif |
|---|
| 253 | 249 | if ((cmd_flags & SDMMC_CMD_PRV_DAT_WAIT) && |
|---|
| .. | .. |
|---|
| 488 | 484 | |
|---|
| 489 | 485 | /* Disable and reset the IDMAC interface */ |
|---|
| 490 | 486 | temp = mci_readl(host, CTRL); |
|---|
| 491 | | - temp &= ~SDMMC_CTRL_USE_IDMAC; |
|---|
| 487 | + if (!host->is_rv1106_sd) |
|---|
| 488 | + temp &= ~SDMMC_CTRL_USE_IDMAC; |
|---|
| 489 | + |
|---|
| 492 | 490 | temp |= SDMMC_CTRL_DMA_RESET; |
|---|
| 493 | 491 | mci_writel(host, CTRL, temp); |
|---|
| 494 | 492 | |
|---|
| 495 | 493 | /* Stop the IDMAC running */ |
|---|
| 496 | 494 | temp = mci_readl(host, BMOD); |
|---|
| 497 | | - temp &= ~(SDMMC_IDMAC_ENABLE | SDMMC_IDMAC_FB); |
|---|
| 498 | | - temp |= SDMMC_IDMAC_SWRESET; |
|---|
| 495 | + if (host->is_rv1106_sd) { |
|---|
| 496 | + temp |= SDMMC_IDMAC_SWRESET; |
|---|
| 497 | + } else { |
|---|
| 498 | + temp &= ~(SDMMC_IDMAC_ENABLE | SDMMC_IDMAC_FB); |
|---|
| 499 | + temp |= SDMMC_IDMAC_SWRESET; |
|---|
| 500 | + } |
|---|
| 499 | 501 | mci_writel(host, BMOD, temp); |
|---|
| 500 | 502 | } |
|---|
| 501 | 503 | |
|---|
| .. | .. |
|---|
| 525 | 527 | tasklet_schedule(&host->tasklet); |
|---|
| 526 | 528 | } |
|---|
| 527 | 529 | |
|---|
| 528 | | - if (host->need_xfer_timer && |
|---|
| 529 | | - host->dir_status == DW_MCI_RECV_STATUS) |
|---|
| 530 | + if (host->need_xfer_timer) |
|---|
| 530 | 531 | del_timer(&host->xfer_timer); |
|---|
| 531 | 532 | } |
|---|
| 532 | 533 | |
|---|
| .. | .. |
|---|
| 736 | 737 | } |
|---|
| 737 | 738 | } |
|---|
| 738 | 739 | |
|---|
| 740 | + if (host->is_rv1106_sd && (data->flags & MMC_DATA_WRITE)) { |
|---|
| 741 | + desc->des0 = desc_last->des0; |
|---|
| 742 | + desc->des2 = desc_last->des2; |
|---|
| 743 | + desc->des1 = RV1106_RAMDON_DATA_SIZE; /* Random dirty data for last one desc */ |
|---|
| 744 | + desc_last = desc; |
|---|
| 745 | + } |
|---|
| 746 | + |
|---|
| 739 | 747 | /* Set first descriptor */ |
|---|
| 740 | 748 | desc_first->des0 |= cpu_to_le32(IDMAC_DES0_FD); |
|---|
| 741 | 749 | |
|---|
| .. | .. |
|---|
| 871 | 879 | if (!host->dms) |
|---|
| 872 | 880 | return -ENOMEM; |
|---|
| 873 | 881 | |
|---|
| 874 | | - host->dms->ch = dma_request_slave_channel(host->dev, "rx-tx"); |
|---|
| 875 | | - if (!host->dms->ch) { |
|---|
| 882 | + host->dms->ch = dma_request_chan(host->dev, "rx-tx"); |
|---|
| 883 | + if (IS_ERR(host->dms->ch)) { |
|---|
| 884 | + int ret = PTR_ERR(host->dms->ch); |
|---|
| 885 | + |
|---|
| 876 | 886 | dev_err(host->dev, "Failed to get external DMA channel.\n"); |
|---|
| 877 | 887 | kfree(host->dms); |
|---|
| 878 | 888 | host->dms = NULL; |
|---|
| 879 | | - return -ENXIO; |
|---|
| 889 | + return ret; |
|---|
| 880 | 890 | } |
|---|
| 881 | 891 | |
|---|
| 882 | 892 | return 0; |
|---|
| .. | .. |
|---|
| 918 | 928 | * non-word-aligned buffers or lengths. Also, we don't bother |
|---|
| 919 | 929 | * with all the DMA setup overhead for short transfers. |
|---|
| 920 | 930 | */ |
|---|
| 921 | | - if (data->blocks * data->blksz < DW_MCI_DMA_THRESHOLD) |
|---|
| 931 | + if (data->blocks * data->blksz < DW_MCI_DMA_THRESHOLD && !host->is_rv1106_sd) |
|---|
| 922 | 932 | return -EINVAL; |
|---|
| 923 | 933 | |
|---|
| 924 | 934 | if (data->blksz & 3) |
|---|
| .. | .. |
|---|
| 976 | 986 | data->host_cookie = COOKIE_UNMAPPED; |
|---|
| 977 | 987 | } |
|---|
| 978 | 988 | |
|---|
| 979 | | -static int dw_mci_set_sdio_status(struct mmc_host *mmc, int val) |
|---|
| 980 | | -{ |
|---|
| 981 | | - struct dw_mci_slot *slot = mmc_priv(mmc); |
|---|
| 982 | | - struct dw_mci *host = slot->host; |
|---|
| 983 | | - |
|---|
| 984 | | - if (!(mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO)) |
|---|
| 985 | | - return 0; |
|---|
| 986 | | - |
|---|
| 987 | | - spin_lock_bh(&host->lock); |
|---|
| 988 | | - |
|---|
| 989 | | - if (val) |
|---|
| 990 | | - set_bit(DW_MMC_CARD_PRESENT, &slot->flags); |
|---|
| 991 | | - else |
|---|
| 992 | | - clear_bit(DW_MMC_CARD_PRESENT, &slot->flags); |
|---|
| 993 | | - |
|---|
| 994 | | - spin_unlock_bh(&host->lock); |
|---|
| 995 | | - |
|---|
| 996 | | - mmc_detect_change(slot->mmc, 20); |
|---|
| 997 | | - |
|---|
| 998 | | - return 0; |
|---|
| 999 | | -} |
|---|
| 1000 | | - |
|---|
| 1001 | 989 | static int dw_mci_get_cd(struct mmc_host *mmc) |
|---|
| 1002 | 990 | { |
|---|
| 1003 | 991 | int present; |
|---|
| 1004 | 992 | struct dw_mci_slot *slot = mmc_priv(mmc); |
|---|
| 1005 | 993 | struct dw_mci *host = slot->host; |
|---|
| 1006 | 994 | int gpio_cd = mmc_gpio_get_cd(mmc); |
|---|
| 1007 | | - |
|---|
| 1008 | | -#ifdef CONFIG_SDIO_KEEPALIVE |
|---|
| 1009 | | - if (mmc->logic_remove_card) |
|---|
| 1010 | | - return test_bit(DW_MMC_CARD_PRESENT, &slot->flags); |
|---|
| 1011 | | -#endif |
|---|
| 1012 | 995 | |
|---|
| 1013 | 996 | /* Use platform get_cd function, else try onboard card detect */ |
|---|
| 1014 | 997 | if (((mmc->caps & MMC_CAP_NEEDS_POLL) |
|---|
| .. | .. |
|---|
| 1358 | 1341 | host->data_status = 0; |
|---|
| 1359 | 1342 | host->dir_status = 0; |
|---|
| 1360 | 1343 | |
|---|
| 1344 | + if (host->is_rv1106_sd) |
|---|
| 1345 | + mci_writel(host, CTYPE, (slot->ctype << slot->id)); |
|---|
| 1346 | + |
|---|
| 1361 | 1347 | data = cmd->data; |
|---|
| 1362 | 1348 | if (data) { |
|---|
| 1363 | 1349 | mci_writel(host, TMOUT, 0xFFFFFFFF); |
|---|
| 1364 | | - mci_writel(host, BYTCNT, data->blksz*data->blocks); |
|---|
| 1350 | + if (host->is_rv1106_sd && (data->flags & MMC_DATA_WRITE)) |
|---|
| 1351 | + mci_writel(host, BYTCNT, 0); |
|---|
| 1352 | + else |
|---|
| 1353 | + mci_writel(host, BYTCNT, data->blksz*data->blocks); |
|---|
| 1365 | 1354 | mci_writel(host, BLKSIZ, data->blksz); |
|---|
| 1366 | 1355 | } |
|---|
| 1367 | 1356 | |
|---|
| .. | .. |
|---|
| 1439 | 1428 | } |
|---|
| 1440 | 1429 | } |
|---|
| 1441 | 1430 | |
|---|
| 1431 | +static bool dw_mci_reset(struct dw_mci *host); |
|---|
| 1442 | 1432 | static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) |
|---|
| 1443 | 1433 | { |
|---|
| 1444 | 1434 | struct dw_mci_slot *slot = mmc_priv(mmc); |
|---|
| .. | .. |
|---|
| 1460 | 1450 | |
|---|
| 1461 | 1451 | spin_lock_bh(&host->lock); |
|---|
| 1462 | 1452 | |
|---|
| 1453 | + if (host->is_rv1106_sd) |
|---|
| 1454 | + dw_mci_reset(host); |
|---|
| 1455 | + |
|---|
| 1463 | 1456 | dw_mci_queue_request(host, slot, mrq); |
|---|
| 1464 | 1457 | |
|---|
| 1465 | 1458 | spin_unlock_bh(&host->lock); |
|---|
| .. | .. |
|---|
| 1469 | 1462 | { |
|---|
| 1470 | 1463 | struct dw_mci_slot *slot = mmc_priv(mmc); |
|---|
| 1471 | 1464 | const struct dw_mci_drv_data *drv_data = slot->host->drv_data; |
|---|
| 1472 | | - u32 regs; |
|---|
| 1465 | + u32 regs, power_off_delay; |
|---|
| 1473 | 1466 | int ret; |
|---|
| 1474 | 1467 | |
|---|
| 1475 | 1468 | switch (ios->bus_width) { |
|---|
| .. | .. |
|---|
| 1508 | 1501 | |
|---|
| 1509 | 1502 | switch (ios->power_mode) { |
|---|
| 1510 | 1503 | case MMC_POWER_UP: |
|---|
| 1511 | | - if (!IS_ERR_OR_NULL(slot->host->pinctrl)) |
|---|
| 1512 | | - pinctrl_select_state(slot->host->pinctrl, slot->host->idle_state); |
|---|
| 1504 | + if (dw_mci_get_cd(mmc) && !IS_ERR_OR_NULL(slot->host->pinctrl)) { |
|---|
| 1505 | + if (!pinctrl_select_state(slot->host->pinctrl, slot->host->idle_state)) { |
|---|
| 1506 | + if (device_property_read_u32(slot->host->dev, "power-off-delay-ms", |
|---|
| 1507 | + &power_off_delay)) |
|---|
| 1508 | + power_off_delay = 200; |
|---|
| 1509 | + msleep(power_off_delay); |
|---|
| 1510 | + } |
|---|
| 1511 | + } |
|---|
| 1513 | 1512 | |
|---|
| 1514 | 1513 | if (!IS_ERR(mmc->supply.vmmc)) { |
|---|
| 1515 | 1514 | ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, |
|---|
| .. | .. |
|---|
| 1544 | 1543 | slot->host->vqmmc_enabled = true; |
|---|
| 1545 | 1544 | } |
|---|
| 1546 | 1545 | |
|---|
| 1546 | +#ifndef CONFIG_ROCKCHIP_THUNDER_BOOT_MMC |
|---|
| 1547 | 1547 | /* Reset our state machine after powering on */ |
|---|
| 1548 | 1548 | dw_mci_ctrl_reset(slot->host, |
|---|
| 1549 | 1549 | SDMMC_CTRL_ALL_RESET_FLAGS); |
|---|
| 1550 | +#endif |
|---|
| 1550 | 1551 | } |
|---|
| 1551 | 1552 | |
|---|
| 1552 | 1553 | /* Adjust clock / bus width after power is up */ |
|---|
| .. | .. |
|---|
| 1563 | 1564 | if (!IS_ERR(mmc->supply.vmmc)) |
|---|
| 1564 | 1565 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); |
|---|
| 1565 | 1566 | |
|---|
| 1566 | | - if (!IS_ERR(mmc->supply.vqmmc) && slot->host->vqmmc_enabled) { |
|---|
| 1567 | | - ios->signal_voltage = MMC_SIGNAL_VOLTAGE_330; |
|---|
| 1568 | | - mmc_regulator_set_vqmmc(mmc, ios); |
|---|
| 1567 | + if (!IS_ERR(mmc->supply.vqmmc) && slot->host->vqmmc_enabled) |
|---|
| 1569 | 1568 | regulator_disable(mmc->supply.vqmmc); |
|---|
| 1570 | | - } |
|---|
| 1571 | 1569 | slot->host->vqmmc_enabled = false; |
|---|
| 1572 | 1570 | |
|---|
| 1573 | 1571 | regs = mci_readl(slot->host, PWREN); |
|---|
| .. | .. |
|---|
| 1621 | 1619 | |
|---|
| 1622 | 1620 | if (!IS_ERR(mmc->supply.vqmmc)) { |
|---|
| 1623 | 1621 | ret = mmc_regulator_set_vqmmc(mmc, ios); |
|---|
| 1624 | | - |
|---|
| 1625 | | - if (ret) { |
|---|
| 1622 | + if (ret < 0) { |
|---|
| 1626 | 1623 | dev_dbg(&mmc->class_dev, |
|---|
| 1627 | 1624 | "Regulator set error %d - %s V\n", |
|---|
| 1628 | 1625 | ret, uhs & v18 ? "1.8" : "3.3"); |
|---|
| .. | .. |
|---|
| 1852 | 1849 | .pre_req = dw_mci_pre_req, |
|---|
| 1853 | 1850 | .post_req = dw_mci_post_req, |
|---|
| 1854 | 1851 | .set_ios = dw_mci_set_ios, |
|---|
| 1855 | | - .set_sdio_status = dw_mci_set_sdio_status, |
|---|
| 1856 | 1852 | .get_ro = dw_mci_get_ro, |
|---|
| 1857 | 1853 | .get_cd = dw_mci_get_cd, |
|---|
| 1858 | 1854 | .hw_reset = dw_mci_hw_reset, |
|---|
| .. | .. |
|---|
| 1874 | 1870 | |
|---|
| 1875 | 1871 | WARN_ON(host->cmd || host->data); |
|---|
| 1876 | 1872 | |
|---|
| 1873 | + if (host->need_xfer_timer) |
|---|
| 1874 | + del_timer(&host->xfer_timer); |
|---|
| 1875 | + |
|---|
| 1877 | 1876 | host->slot->mrq = NULL; |
|---|
| 1878 | 1877 | host->mrq = NULL; |
|---|
| 1879 | 1878 | if (!list_empty(&host->queue)) { |
|---|
| .. | .. |
|---|
| 1894 | 1893 | } |
|---|
| 1895 | 1894 | |
|---|
| 1896 | 1895 | spin_unlock(&host->lock); |
|---|
| 1896 | + |
|---|
| 1897 | 1897 | mmc_request_done(prev_mmc, mrq); |
|---|
| 1898 | 1898 | spin_lock(&host->lock); |
|---|
| 1899 | 1899 | } |
|---|
| .. | .. |
|---|
| 1935 | 1935 | { |
|---|
| 1936 | 1936 | u32 status = host->data_status; |
|---|
| 1937 | 1937 | |
|---|
| 1938 | + if (host->is_rv1106_sd && (data->flags & MMC_DATA_WRITE) && (status & SDMMC_INT_DATA_OVER)) |
|---|
| 1939 | + goto finish; |
|---|
| 1940 | + |
|---|
| 1938 | 1941 | if (status & DW_MCI_DATA_ERROR_FLAGS) { |
|---|
| 1939 | 1942 | if (status & SDMMC_INT_DRTO) { |
|---|
| 1940 | 1943 | data->error = -ETIMEDOUT; |
|---|
| .. | .. |
|---|
| 1967 | 1970 | */ |
|---|
| 1968 | 1971 | dw_mci_reset(host); |
|---|
| 1969 | 1972 | } else { |
|---|
| 1973 | +finish: |
|---|
| 1970 | 1974 | data->bytes_xfered = data->blocks * data->blksz; |
|---|
| 1971 | 1975 | data->error = 0; |
|---|
| 1972 | 1976 | } |
|---|
| .. | .. |
|---|
| 2014 | 2018 | host->bus_hz); |
|---|
| 2015 | 2019 | |
|---|
| 2016 | 2020 | /* add a bit spare time */ |
|---|
| 2017 | | - xfer_ms += 100; |
|---|
| 2018 | | - |
|---|
| 2021 | + if (host->dir_status == DW_MCI_RECV_STATUS) |
|---|
| 2022 | + xfer_ms += 100; |
|---|
| 2023 | + else |
|---|
| 2024 | + xfer_ms += 2500; |
|---|
| 2019 | 2025 | spin_lock_irqsave(&host->irq_lock, irqflags); |
|---|
| 2020 | 2026 | if (!test_bit(EVENT_XFER_COMPLETE, &host->pending_events)) |
|---|
| 2021 | 2027 | mod_timer(&host->xfer_timer, |
|---|
| .. | .. |
|---|
| 2132 | 2138 | } |
|---|
| 2133 | 2139 | |
|---|
| 2134 | 2140 | prev_state = state = STATE_SENDING_DATA; |
|---|
| 2135 | | - /* fall through */ |
|---|
| 2141 | + fallthrough; |
|---|
| 2136 | 2142 | |
|---|
| 2137 | 2143 | case STATE_SENDING_DATA: |
|---|
| 2138 | 2144 | /* |
|---|
| .. | .. |
|---|
| 2150 | 2156 | send_stop_abort(host, data); |
|---|
| 2151 | 2157 | dw_mci_stop_dma(host); |
|---|
| 2152 | 2158 | state = STATE_DATA_ERROR; |
|---|
| 2159 | + if (host->dir_status == DW_MCI_SEND_STATUS) { |
|---|
| 2160 | + data->bytes_xfered = 0; |
|---|
| 2161 | + data->error = -ETIMEDOUT; |
|---|
| 2162 | + host->data = NULL; |
|---|
| 2163 | + dw_mci_request_end(host, mrq); |
|---|
| 2164 | + goto unlock; |
|---|
| 2165 | + } |
|---|
| 2153 | 2166 | break; |
|---|
| 2154 | 2167 | } |
|---|
| 2155 | 2168 | |
|---|
| .. | .. |
|---|
| 2161 | 2174 | */ |
|---|
| 2162 | 2175 | if (host->dir_status == DW_MCI_RECV_STATUS) |
|---|
| 2163 | 2176 | dw_mci_set_drto(host); |
|---|
| 2164 | | - if (host->need_xfer_timer && |
|---|
| 2165 | | - host->dir_status == DW_MCI_RECV_STATUS) |
|---|
| 2177 | + if (host->need_xfer_timer) |
|---|
| 2166 | 2178 | dw_mci_set_xfer_timeout(host); |
|---|
| 2167 | 2179 | break; |
|---|
| 2168 | 2180 | } |
|---|
| .. | .. |
|---|
| 2193 | 2205 | } |
|---|
| 2194 | 2206 | prev_state = state = STATE_DATA_BUSY; |
|---|
| 2195 | 2207 | |
|---|
| 2196 | | - /* fall through */ |
|---|
| 2208 | + fallthrough; |
|---|
| 2197 | 2209 | |
|---|
| 2198 | 2210 | case STATE_DATA_BUSY: |
|---|
| 2199 | 2211 | if (!dw_mci_clear_pending_data_complete(host)) { |
|---|
| .. | .. |
|---|
| 2204 | 2216 | */ |
|---|
| 2205 | 2217 | if (host->dir_status == DW_MCI_RECV_STATUS) |
|---|
| 2206 | 2218 | dw_mci_set_drto(host); |
|---|
| 2219 | + if (host->need_xfer_timer && host->dir_status == DW_MCI_SEND_STATUS) |
|---|
| 2220 | + dw_mci_set_xfer_timeout(host); |
|---|
| 2207 | 2221 | break; |
|---|
| 2208 | 2222 | } |
|---|
| 2209 | 2223 | |
|---|
| .. | .. |
|---|
| 2220 | 2234 | } |
|---|
| 2221 | 2235 | |
|---|
| 2222 | 2236 | /* stop command for open-ended transfer*/ |
|---|
| 2223 | | - if (data->stop) |
|---|
| 2237 | + if (data->stop) { |
|---|
| 2238 | + if (host->is_rv1106_sd && (data->flags & MMC_DATA_WRITE)) { |
|---|
| 2239 | + int fifo_count; |
|---|
| 2240 | + |
|---|
| 2241 | + if (readl_poll_timeout_atomic(host->regs + SDMMC_STATUS, fifo_count, |
|---|
| 2242 | + ((fifo_count >> 17) & 0x7FF) <= RV1106_RAMDON_DATA_SIZE / 4, |
|---|
| 2243 | + 0, 5000 * USEC_PER_MSEC)) |
|---|
| 2244 | + data->error = -ETIMEDOUT; |
|---|
| 2245 | + udelay(1); |
|---|
| 2246 | + dw_mci_reset(host); |
|---|
| 2247 | + } |
|---|
| 2224 | 2248 | send_stop_abort(host, data); |
|---|
| 2249 | + } |
|---|
| 2225 | 2250 | } else { |
|---|
| 2226 | 2251 | /* |
|---|
| 2227 | 2252 | * If we don't have a command complete now we'll |
|---|
| .. | .. |
|---|
| 2246 | 2271 | */ |
|---|
| 2247 | 2272 | prev_state = state = STATE_SENDING_STOP; |
|---|
| 2248 | 2273 | |
|---|
| 2249 | | - /* fall through */ |
|---|
| 2274 | + fallthrough; |
|---|
| 2250 | 2275 | |
|---|
| 2251 | 2276 | case STATE_SENDING_STOP: |
|---|
| 2252 | 2277 | if (!dw_mci_clear_pending_cmd_complete(host)) |
|---|
| .. | .. |
|---|
| 2752 | 2777 | del_timer(&host->cto_timer); |
|---|
| 2753 | 2778 | mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS); |
|---|
| 2754 | 2779 | host->cmd_status = pending; |
|---|
| 2755 | | - if ((host->need_xfer_timer) && |
|---|
| 2756 | | - host->dir_status == DW_MCI_RECV_STATUS) |
|---|
| 2780 | + if (host->need_xfer_timer) |
|---|
| 2757 | 2781 | del_timer(&host->xfer_timer); |
|---|
| 2758 | 2782 | smp_wmb(); /* drain writebuffer */ |
|---|
| 2759 | 2783 | set_bit(EVENT_CMD_COMPLETE, &host->pending_events); |
|---|
| .. | .. |
|---|
| 2771 | 2795 | } |
|---|
| 2772 | 2796 | |
|---|
| 2773 | 2797 | if (pending & SDMMC_INT_DATA_OVER) { |
|---|
| 2798 | +rv1106_sd: |
|---|
| 2774 | 2799 | spin_lock_irqsave(&host->irq_lock, irqflags); |
|---|
| 2775 | 2800 | |
|---|
| 2776 | 2801 | del_timer(&host->dto_timer); |
|---|
| 2777 | 2802 | |
|---|
| 2778 | 2803 | mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER); |
|---|
| 2804 | + if (host->is_rv1106_sd) |
|---|
| 2805 | + pending |= SDMMC_INT_DATA_OVER; |
|---|
| 2779 | 2806 | if (!host->data_status) |
|---|
| 2780 | 2807 | host->data_status = pending; |
|---|
| 2781 | 2808 | smp_wmb(); /* drain writebuffer */ |
|---|
| .. | .. |
|---|
| 2845 | 2872 | mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI); |
|---|
| 2846 | 2873 | if (!test_bit(EVENT_DATA_ERROR, &host->pending_events)) |
|---|
| 2847 | 2874 | host->dma_ops->complete((void *)host); |
|---|
| 2875 | + |
|---|
| 2876 | + if (host->is_rv1106_sd && (pending & SDMMC_IDMAC_INT_TI)) |
|---|
| 2877 | + goto rv1106_sd; |
|---|
| 2848 | 2878 | } |
|---|
| 2849 | 2879 | } |
|---|
| 2850 | 2880 | |
|---|
| .. | .. |
|---|
| 2860 | 2890 | |
|---|
| 2861 | 2891 | if (host->pdata->caps) |
|---|
| 2862 | 2892 | mmc->caps = host->pdata->caps; |
|---|
| 2863 | | - |
|---|
| 2864 | | - /* |
|---|
| 2865 | | - * Support MMC_CAP_ERASE by default. |
|---|
| 2866 | | - * It needs to use trim/discard/erase commands. |
|---|
| 2867 | | - */ |
|---|
| 2868 | | - mmc->caps |= MMC_CAP_ERASE; |
|---|
| 2869 | 2893 | |
|---|
| 2870 | 2894 | if (host->pdata->pm_caps) |
|---|
| 2871 | 2895 | mmc->pm_caps = host->pdata->pm_caps; |
|---|
| .. | .. |
|---|
| 2884 | 2908 | ctrl_id); |
|---|
| 2885 | 2909 | return -EINVAL; |
|---|
| 2886 | 2910 | } |
|---|
| 2887 | | - /* |
|---|
| 2888 | | - * Some sd cards violate the spec. They claim to support |
|---|
| 2889 | | - * CMD23 but actually not. We don't have a good method to |
|---|
| 2890 | | - * work around them except for adding MMC_QUIRK_BLK_NO_CMD23 |
|---|
| 2891 | | - * one by one. But it's not a acceptable way for our custmors. |
|---|
| 2892 | | - * So removing CMD23 support for all sd cards to solve it. |
|---|
| 2893 | | - */ |
|---|
| 2894 | | - if (!(mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)) |
|---|
| 2895 | | - mmc->caps |= drv_data->caps[ctrl_id]; |
|---|
| 2911 | + mmc->caps |= drv_data->caps[ctrl_id]; |
|---|
| 2896 | 2912 | } |
|---|
| 2897 | 2913 | |
|---|
| 2898 | 2914 | if (host->pdata->caps2) |
|---|
| .. | .. |
|---|
| 2946 | 2962 | |
|---|
| 2947 | 2963 | /* Useful defaults if platform data is unset. */ |
|---|
| 2948 | 2964 | if (host->use_dma == TRANS_MODE_IDMAC) { |
|---|
| 2965 | + /* Reserve last desc for dirty data */ |
|---|
| 2966 | + if (host->is_rv1106_sd) |
|---|
| 2967 | + host->ring_size--; |
|---|
| 2968 | + |
|---|
| 2949 | 2969 | mmc->max_segs = host->ring_size; |
|---|
| 2950 | 2970 | mmc->max_blk_size = 65535; |
|---|
| 2951 | 2971 | mmc->max_seg_size = 0x1000; |
|---|
| .. | .. |
|---|
| 2969 | 2989 | } |
|---|
| 2970 | 2990 | |
|---|
| 2971 | 2991 | dw_mci_get_cd(mmc); |
|---|
| 2972 | | - |
|---|
| 2973 | | -#ifdef CONFIG_SDIO_KEEPALIVE |
|---|
| 2974 | | - if (mmc->logic_remove_card) |
|---|
| 2975 | | - clear_bit(DW_MMC_CARD_PRESENT, &slot->flags); |
|---|
| 2976 | | -#endif |
|---|
| 2977 | 2992 | |
|---|
| 2978 | 2993 | ret = mmc_add_host(mmc); |
|---|
| 2979 | 2994 | if (ret) |
|---|
| .. | .. |
|---|
| 3336 | 3351 | |
|---|
| 3337 | 3352 | if (!host->pdata) { |
|---|
| 3338 | 3353 | host->pdata = dw_mci_parse_dt(host); |
|---|
| 3339 | | - if (PTR_ERR(host->pdata) == -EPROBE_DEFER) { |
|---|
| 3340 | | - return -EPROBE_DEFER; |
|---|
| 3341 | | - } else if (IS_ERR(host->pdata)) { |
|---|
| 3342 | | - dev_err(host->dev, "platform data not available\n"); |
|---|
| 3343 | | - return -EINVAL; |
|---|
| 3344 | | - } |
|---|
| 3354 | + if (IS_ERR(host->pdata)) |
|---|
| 3355 | + return dev_err_probe(host->dev, PTR_ERR(host->pdata), |
|---|
| 3356 | + "platform data not available\n"); |
|---|
| 3345 | 3357 | } |
|---|
| 3346 | 3358 | |
|---|
| 3347 | 3359 | host->biu_clk = devm_clk_get(host->dev, "biu"); |
|---|
| .. | .. |
|---|
| 3354 | 3366 | return ret; |
|---|
| 3355 | 3367 | } |
|---|
| 3356 | 3368 | } |
|---|
| 3369 | + |
|---|
| 3357 | 3370 | #ifdef CONFIG_ROCKCHIP_THUNDER_BOOT_MMC |
|---|
| 3358 | | - if (device_property_read_bool(host->dev, "supports-emmc")) { |
|---|
| 3371 | + if (device_property_read_bool(host->dev, "no-sd") && |
|---|
| 3372 | + device_property_read_bool(host->dev, "no-sdio")) { |
|---|
| 3359 | 3373 | if (readl_poll_timeout(host->regs + SDMMC_STATUS, |
|---|
| 3360 | 3374 | fifo_size, |
|---|
| 3361 | 3375 | !(fifo_size & (BIT(10) | GENMASK(7, 4))), |
|---|
| .. | .. |
|---|
| 3532 | 3546 | goto err_dmaunmap; |
|---|
| 3533 | 3547 | } |
|---|
| 3534 | 3548 | |
|---|
| 3549 | + if (host->is_rv1106_sd) { |
|---|
| 3550 | +#if IS_ENABLED(CONFIG_CPU_RV1106) |
|---|
| 3551 | + g_sdmmc_ispvicap_lock = &host->lock; |
|---|
| 3552 | +#endif |
|---|
| 3553 | + /* Select IDMAC interface */ |
|---|
| 3554 | + fifo_size = mci_readl(host, CTRL); |
|---|
| 3555 | + fifo_size |= SDMMC_CTRL_USE_IDMAC; |
|---|
| 3556 | + mci_writel(host, CTRL, fifo_size); |
|---|
| 3557 | + |
|---|
| 3558 | + fifo_size = mci_readl(host, INTMASK); |
|---|
| 3559 | + fifo_size &= ~SDMMC_INT_HTO; |
|---|
| 3560 | + mci_writel(host, INTMASK, fifo_size); |
|---|
| 3561 | + |
|---|
| 3562 | + host->slot->mmc->caps &= ~(MMC_CAP_UHS_DDR50 | MMC_CAP_UHS_SDR104 | |
|---|
| 3563 | + MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 | |
|---|
| 3564 | + MMC_CAP_UHS_SDR12); |
|---|
| 3565 | + } |
|---|
| 3566 | + |
|---|
| 3535 | 3567 | /* Now that slots are all setup, we can enable card detect */ |
|---|
| 3536 | 3568 | dw_mci_enable_cd(host); |
|---|
| 3537 | 3569 | |
|---|
| .. | .. |
|---|
| 3629 | 3661 | * Restore the initial value at FIFOTH register |
|---|
| 3630 | 3662 | * And Invalidate the prev_blksz with zero |
|---|
| 3631 | 3663 | */ |
|---|
| 3632 | | - mci_writel(host, FIFOTH, host->fifoth_val); |
|---|
| 3633 | | - host->prev_blksz = 0; |
|---|
| 3664 | + mci_writel(host, FIFOTH, host->fifoth_val); |
|---|
| 3665 | + host->prev_blksz = 0; |
|---|
| 3634 | 3666 | |
|---|
| 3635 | 3667 | /* Put in max timeout */ |
|---|
| 3636 | 3668 | mci_writel(host, TMOUT, 0xFFFFFFFF); |
|---|
| 3637 | 3669 | |
|---|
| 3638 | 3670 | mci_writel(host, RINTSTS, 0xFFFFFFFF); |
|---|
| 3639 | | - mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | |
|---|
| 3640 | | - SDMMC_INT_TXDR | SDMMC_INT_RXDR | |
|---|
| 3641 | | - DW_MCI_ERROR_FLAGS); |
|---|
| 3671 | + mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | DW_MCI_ERROR_FLAGS); |
|---|
| 3642 | 3672 | mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); |
|---|
| 3643 | 3673 | |
|---|
| 3674 | + if (host->is_rv1106_sd) { |
|---|
| 3675 | + /* Select IDMAC interface */ |
|---|
| 3676 | + ret = mci_readl(host, CTRL); |
|---|
| 3677 | + ret |= SDMMC_CTRL_USE_IDMAC; |
|---|
| 3678 | + mci_writel(host, CTRL, ret); |
|---|
| 3644 | 3679 | |
|---|
| 3645 | | - if (host->slot->mmc->pm_flags & MMC_PM_KEEP_POWER) |
|---|
| 3680 | + ret = mci_readl(host, INTMASK); |
|---|
| 3681 | + ret &= ~SDMMC_INT_HTO; |
|---|
| 3682 | + mci_writel(host, INTMASK, ret); |
|---|
| 3683 | + } |
|---|
| 3684 | + |
|---|
| 3685 | + if (host->slot && host->slot->mmc->pm_flags & MMC_PM_KEEP_POWER) |
|---|
| 3646 | 3686 | dw_mci_set_ios(host->slot->mmc, &host->slot->mmc->ios); |
|---|
| 3647 | 3687 | |
|---|
| 3648 | 3688 | /* Force setup bus to guarantee available clock output */ |
|---|