diff options
-rw-r--r-- | drivers/mmc/host/sdhci-tegra.c | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 02d8f524bb9e..7bc950520fd9 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
@@ -4,6 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/delay.h> | 6 | #include <linux/delay.h> |
7 | #include <linux/dma-mapping.h> | ||
7 | #include <linux/err.h> | 8 | #include <linux/err.h> |
8 | #include <linux/module.h> | 9 | #include <linux/module.h> |
9 | #include <linux/init.h> | 10 | #include <linux/init.h> |
@@ -104,6 +105,7 @@ | |||
104 | 105 | ||
105 | struct sdhci_tegra_soc_data { | 106 | struct sdhci_tegra_soc_data { |
106 | const struct sdhci_pltfm_data *pdata; | 107 | const struct sdhci_pltfm_data *pdata; |
108 | u64 dma_mask; | ||
107 | u32 nvquirks; | 109 | u32 nvquirks; |
108 | u8 min_tap_delay; | 110 | u8 min_tap_delay; |
109 | u8 max_tap_delay; | 111 | u8 max_tap_delay; |
@@ -1233,11 +1235,25 @@ static const struct cqhci_host_ops sdhci_tegra_cqhci_ops = { | |||
1233 | .update_dcmd_desc = sdhci_tegra_update_dcmd_desc, | 1235 | .update_dcmd_desc = sdhci_tegra_update_dcmd_desc, |
1234 | }; | 1236 | }; |
1235 | 1237 | ||
1238 | static int tegra_sdhci_set_dma_mask(struct sdhci_host *host) | ||
1239 | { | ||
1240 | struct sdhci_pltfm_host *platform = sdhci_priv(host); | ||
1241 | struct sdhci_tegra *tegra = sdhci_pltfm_priv(platform); | ||
1242 | const struct sdhci_tegra_soc_data *soc = tegra->soc_data; | ||
1243 | struct device *dev = mmc_dev(host->mmc); | ||
1244 | |||
1245 | if (soc->dma_mask) | ||
1246 | return dma_set_mask_and_coherent(dev, soc->dma_mask); | ||
1247 | |||
1248 | return 0; | ||
1249 | } | ||
1250 | |||
1236 | static const struct sdhci_ops tegra_sdhci_ops = { | 1251 | static const struct sdhci_ops tegra_sdhci_ops = { |
1237 | .get_ro = tegra_sdhci_get_ro, | 1252 | .get_ro = tegra_sdhci_get_ro, |
1238 | .read_w = tegra_sdhci_readw, | 1253 | .read_w = tegra_sdhci_readw, |
1239 | .write_l = tegra_sdhci_writel, | 1254 | .write_l = tegra_sdhci_writel, |
1240 | .set_clock = tegra_sdhci_set_clock, | 1255 | .set_clock = tegra_sdhci_set_clock, |
1256 | .set_dma_mask = tegra_sdhci_set_dma_mask, | ||
1241 | .set_bus_width = sdhci_set_bus_width, | 1257 | .set_bus_width = sdhci_set_bus_width, |
1242 | .reset = tegra_sdhci_reset, | 1258 | .reset = tegra_sdhci_reset, |
1243 | .platform_execute_tuning = tegra_sdhci_execute_tuning, | 1259 | .platform_execute_tuning = tegra_sdhci_execute_tuning, |
@@ -1257,6 +1273,7 @@ static const struct sdhci_pltfm_data sdhci_tegra20_pdata = { | |||
1257 | 1273 | ||
1258 | static const struct sdhci_tegra_soc_data soc_data_tegra20 = { | 1274 | static const struct sdhci_tegra_soc_data soc_data_tegra20 = { |
1259 | .pdata = &sdhci_tegra20_pdata, | 1275 | .pdata = &sdhci_tegra20_pdata, |
1276 | .dma_mask = DMA_BIT_MASK(32), | ||
1260 | .nvquirks = NVQUIRK_FORCE_SDHCI_SPEC_200 | | 1277 | .nvquirks = NVQUIRK_FORCE_SDHCI_SPEC_200 | |
1261 | NVQUIRK_ENABLE_BLOCK_GAP_DET, | 1278 | NVQUIRK_ENABLE_BLOCK_GAP_DET, |
1262 | }; | 1279 | }; |
@@ -1283,6 +1300,7 @@ static const struct sdhci_pltfm_data sdhci_tegra30_pdata = { | |||
1283 | 1300 | ||
1284 | static const struct sdhci_tegra_soc_data soc_data_tegra30 = { | 1301 | static const struct sdhci_tegra_soc_data soc_data_tegra30 = { |
1285 | .pdata = &sdhci_tegra30_pdata, | 1302 | .pdata = &sdhci_tegra30_pdata, |
1303 | .dma_mask = DMA_BIT_MASK(32), | ||
1286 | .nvquirks = NVQUIRK_ENABLE_SDHCI_SPEC_300 | | 1304 | .nvquirks = NVQUIRK_ENABLE_SDHCI_SPEC_300 | |
1287 | NVQUIRK_ENABLE_SDR50 | | 1305 | NVQUIRK_ENABLE_SDR50 | |
1288 | NVQUIRK_ENABLE_SDR104 | | 1306 | NVQUIRK_ENABLE_SDR104 | |
@@ -1295,6 +1313,7 @@ static const struct sdhci_ops tegra114_sdhci_ops = { | |||
1295 | .write_w = tegra_sdhci_writew, | 1313 | .write_w = tegra_sdhci_writew, |
1296 | .write_l = tegra_sdhci_writel, | 1314 | .write_l = tegra_sdhci_writel, |
1297 | .set_clock = tegra_sdhci_set_clock, | 1315 | .set_clock = tegra_sdhci_set_clock, |
1316 | .set_dma_mask = tegra_sdhci_set_dma_mask, | ||
1298 | .set_bus_width = sdhci_set_bus_width, | 1317 | .set_bus_width = sdhci_set_bus_width, |
1299 | .reset = tegra_sdhci_reset, | 1318 | .reset = tegra_sdhci_reset, |
1300 | .platform_execute_tuning = tegra_sdhci_execute_tuning, | 1319 | .platform_execute_tuning = tegra_sdhci_execute_tuning, |
@@ -1316,6 +1335,7 @@ static const struct sdhci_pltfm_data sdhci_tegra114_pdata = { | |||
1316 | 1335 | ||
1317 | static const struct sdhci_tegra_soc_data soc_data_tegra114 = { | 1336 | static const struct sdhci_tegra_soc_data soc_data_tegra114 = { |
1318 | .pdata = &sdhci_tegra114_pdata, | 1337 | .pdata = &sdhci_tegra114_pdata, |
1338 | .dma_mask = DMA_BIT_MASK(32), | ||
1319 | }; | 1339 | }; |
1320 | 1340 | ||
1321 | static const struct sdhci_pltfm_data sdhci_tegra124_pdata = { | 1341 | static const struct sdhci_pltfm_data sdhci_tegra124_pdata = { |
@@ -1325,22 +1345,13 @@ static const struct sdhci_pltfm_data sdhci_tegra124_pdata = { | |||
1325 | SDHCI_QUIRK_NO_HISPD_BIT | | 1345 | SDHCI_QUIRK_NO_HISPD_BIT | |
1326 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | | 1346 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | |
1327 | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, | 1347 | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, |
1328 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | 1348 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, |
1329 | /* | ||
1330 | * The TRM states that the SD/MMC controller found on | ||
1331 | * Tegra124 can address 34 bits (the maximum supported by | ||
1332 | * the Tegra memory controller), but tests show that DMA | ||
1333 | * to or from above 4 GiB doesn't work. This is possibly | ||
1334 | * caused by missing programming, though it's not obvious | ||
1335 | * what sequence is required. Mark 64-bit DMA broken for | ||
1336 | * now to fix this for existing users (e.g. Nyan boards). | ||
1337 | */ | ||
1338 | SDHCI_QUIRK2_BROKEN_64_BIT_DMA, | ||
1339 | .ops = &tegra114_sdhci_ops, | 1349 | .ops = &tegra114_sdhci_ops, |
1340 | }; | 1350 | }; |
1341 | 1351 | ||
1342 | static const struct sdhci_tegra_soc_data soc_data_tegra124 = { | 1352 | static const struct sdhci_tegra_soc_data soc_data_tegra124 = { |
1343 | .pdata = &sdhci_tegra124_pdata, | 1353 | .pdata = &sdhci_tegra124_pdata, |
1354 | .dma_mask = DMA_BIT_MASK(34), | ||
1344 | }; | 1355 | }; |
1345 | 1356 | ||
1346 | static const struct sdhci_ops tegra210_sdhci_ops = { | 1357 | static const struct sdhci_ops tegra210_sdhci_ops = { |
@@ -1349,6 +1360,7 @@ static const struct sdhci_ops tegra210_sdhci_ops = { | |||
1349 | .write_w = tegra210_sdhci_writew, | 1360 | .write_w = tegra210_sdhci_writew, |
1350 | .write_l = tegra_sdhci_writel, | 1361 | .write_l = tegra_sdhci_writel, |
1351 | .set_clock = tegra_sdhci_set_clock, | 1362 | .set_clock = tegra_sdhci_set_clock, |
1363 | .set_dma_mask = tegra_sdhci_set_dma_mask, | ||
1352 | .set_bus_width = sdhci_set_bus_width, | 1364 | .set_bus_width = sdhci_set_bus_width, |
1353 | .reset = tegra_sdhci_reset, | 1365 | .reset = tegra_sdhci_reset, |
1354 | .set_uhs_signaling = tegra_sdhci_set_uhs_signaling, | 1366 | .set_uhs_signaling = tegra_sdhci_set_uhs_signaling, |
@@ -1369,6 +1381,7 @@ static const struct sdhci_pltfm_data sdhci_tegra210_pdata = { | |||
1369 | 1381 | ||
1370 | static const struct sdhci_tegra_soc_data soc_data_tegra210 = { | 1382 | static const struct sdhci_tegra_soc_data soc_data_tegra210 = { |
1371 | .pdata = &sdhci_tegra210_pdata, | 1383 | .pdata = &sdhci_tegra210_pdata, |
1384 | .dma_mask = DMA_BIT_MASK(34), | ||
1372 | .nvquirks = NVQUIRK_NEEDS_PAD_CONTROL | | 1385 | .nvquirks = NVQUIRK_NEEDS_PAD_CONTROL | |
1373 | NVQUIRK_HAS_PADCALIB | | 1386 | NVQUIRK_HAS_PADCALIB | |
1374 | NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | | 1387 | NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | |
@@ -1383,6 +1396,7 @@ static const struct sdhci_ops tegra186_sdhci_ops = { | |||
1383 | .read_w = tegra_sdhci_readw, | 1396 | .read_w = tegra_sdhci_readw, |
1384 | .write_l = tegra_sdhci_writel, | 1397 | .write_l = tegra_sdhci_writel, |
1385 | .set_clock = tegra_sdhci_set_clock, | 1398 | .set_clock = tegra_sdhci_set_clock, |
1399 | .set_dma_mask = tegra_sdhci_set_dma_mask, | ||
1386 | .set_bus_width = sdhci_set_bus_width, | 1400 | .set_bus_width = sdhci_set_bus_width, |
1387 | .reset = tegra_sdhci_reset, | 1401 | .reset = tegra_sdhci_reset, |
1388 | .set_uhs_signaling = tegra_sdhci_set_uhs_signaling, | 1402 | .set_uhs_signaling = tegra_sdhci_set_uhs_signaling, |
@@ -1398,20 +1412,13 @@ static const struct sdhci_pltfm_data sdhci_tegra186_pdata = { | |||
1398 | SDHCI_QUIRK_NO_HISPD_BIT | | 1412 | SDHCI_QUIRK_NO_HISPD_BIT | |
1399 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | | 1413 | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | |
1400 | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, | 1414 | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, |
1401 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | | 1415 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, |
1402 | /* SDHCI controllers on Tegra186 support 40-bit addressing. | ||
1403 | * IOVA addresses are 48-bit wide on Tegra186. | ||
1404 | * With 64-bit dma mask used for SDHCI, accesses can | ||
1405 | * be broken. Disable 64-bit dma, which would fall back | ||
1406 | * to 32-bit dma mask. Ideally 40-bit dma mask would work, | ||
1407 | * But it is not supported as of now. | ||
1408 | */ | ||
1409 | SDHCI_QUIRK2_BROKEN_64_BIT_DMA, | ||
1410 | .ops = &tegra186_sdhci_ops, | 1416 | .ops = &tegra186_sdhci_ops, |
1411 | }; | 1417 | }; |
1412 | 1418 | ||
1413 | static const struct sdhci_tegra_soc_data soc_data_tegra186 = { | 1419 | static const struct sdhci_tegra_soc_data soc_data_tegra186 = { |
1414 | .pdata = &sdhci_tegra186_pdata, | 1420 | .pdata = &sdhci_tegra186_pdata, |
1421 | .dma_mask = DMA_BIT_MASK(40), | ||
1415 | .nvquirks = NVQUIRK_NEEDS_PAD_CONTROL | | 1422 | .nvquirks = NVQUIRK_NEEDS_PAD_CONTROL | |
1416 | NVQUIRK_HAS_PADCALIB | | 1423 | NVQUIRK_HAS_PADCALIB | |
1417 | NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | | 1424 | NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | |
@@ -1424,6 +1431,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra186 = { | |||
1424 | 1431 | ||
1425 | static const struct sdhci_tegra_soc_data soc_data_tegra194 = { | 1432 | static const struct sdhci_tegra_soc_data soc_data_tegra194 = { |
1426 | .pdata = &sdhci_tegra186_pdata, | 1433 | .pdata = &sdhci_tegra186_pdata, |
1434 | .dma_mask = DMA_BIT_MASK(39), | ||
1427 | .nvquirks = NVQUIRK_NEEDS_PAD_CONTROL | | 1435 | .nvquirks = NVQUIRK_NEEDS_PAD_CONTROL | |
1428 | NVQUIRK_HAS_PADCALIB | | 1436 | NVQUIRK_HAS_PADCALIB | |
1429 | NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | | 1437 | NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | |