| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Driver for sunxi SD/MMC host controllers |
|---|
| 3 | 4 | * (C) Copyright 2007-2011 Reuuimlla Technology Co., Ltd. |
|---|
| .. | .. |
|---|
| 6 | 7 | * (C) Copyright 2013-2014 David Lanzendörfer <david.lanzendoerfer@o2s.ch> |
|---|
| 7 | 8 | * (C) Copyright 2013-2014 Hans de Goede <hdegoede@redhat.com> |
|---|
| 8 | 9 | * (C) Copyright 2017 Sootech SA |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or |
|---|
| 11 | | - * modify it under the terms of the GNU General Public License as |
|---|
| 12 | | - * published by the Free Software Foundation; either version 2 of |
|---|
| 13 | | - * the License, or (at your option) any later version. |
|---|
| 14 | 10 | */ |
|---|
| 15 | 11 | |
|---|
| 16 | 12 | #include <linux/clk.h> |
|---|
| .. | .. |
|---|
| 19 | 15 | #include <linux/device.h> |
|---|
| 20 | 16 | #include <linux/dma-mapping.h> |
|---|
| 21 | 17 | #include <linux/err.h> |
|---|
| 22 | | -#include <linux/gpio.h> |
|---|
| 23 | 18 | #include <linux/interrupt.h> |
|---|
| 24 | 19 | #include <linux/io.h> |
|---|
| 25 | 20 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 32 | 27 | #include <linux/mmc/slot-gpio.h> |
|---|
| 33 | 28 | #include <linux/module.h> |
|---|
| 34 | 29 | #include <linux/of_address.h> |
|---|
| 35 | | -#include <linux/of_gpio.h> |
|---|
| 36 | 30 | #include <linux/of_platform.h> |
|---|
| 37 | 31 | #include <linux/platform_device.h> |
|---|
| 38 | 32 | #include <linux/pm_runtime.h> |
|---|
| .. | .. |
|---|
| 258 | 252 | /* Does DATA0 needs to be masked while the clock is updated */ |
|---|
| 259 | 253 | bool mask_data0; |
|---|
| 260 | 254 | |
|---|
| 261 | | - /* hardware only supports new timing mode */ |
|---|
| 255 | + /* |
|---|
| 256 | + * hardware only supports new timing mode, either due to lack of |
|---|
| 257 | + * a mode switch in the clock controller, or the mmc controller |
|---|
| 258 | + * is permanently configured in the new timing mode, without the |
|---|
| 259 | + * NTSR mode switch. |
|---|
| 260 | + */ |
|---|
| 262 | 261 | bool needs_new_timings; |
|---|
| 263 | 262 | |
|---|
| 264 | | - /* hardware can switch between old and new timing modes */ |
|---|
| 265 | | - bool has_timings_switch; |
|---|
| 263 | + /* clock hardware can switch between old and new timing modes */ |
|---|
| 264 | + bool ccu_has_timings_switch; |
|---|
| 266 | 265 | }; |
|---|
| 267 | 266 | |
|---|
| 268 | 267 | struct sunxi_mmc_host { |
|---|
| .. | .. |
|---|
| 787 | 786 | clock <<= 1; |
|---|
| 788 | 787 | } |
|---|
| 789 | 788 | |
|---|
| 790 | | - if (host->use_new_timings && host->cfg->has_timings_switch) { |
|---|
| 789 | + if (host->use_new_timings && host->cfg->ccu_has_timings_switch) { |
|---|
| 791 | 790 | ret = sunxi_ccu_set_mmc_timing_mode(host->clk_mmc, true); |
|---|
| 792 | 791 | if (ret) { |
|---|
| 793 | 792 | dev_err(mmc_dev(mmc), |
|---|
| .. | .. |
|---|
| 822 | 821 | /* update card clock rate to account for internal divider */ |
|---|
| 823 | 822 | rate /= div; |
|---|
| 824 | 823 | |
|---|
| 824 | + /* |
|---|
| 825 | + * Configure the controller to use the new timing mode if needed. |
|---|
| 826 | + * On controllers that only support the new timing mode, such as |
|---|
| 827 | + * the eMMC controller on the A64, this register does not exist, |
|---|
| 828 | + * and any writes to it are ignored. |
|---|
| 829 | + */ |
|---|
| 825 | 830 | if (host->use_new_timings) { |
|---|
| 826 | 831 | /* Don't touch the delay bits */ |
|---|
| 827 | 832 | rval = mmc_readl(host, REG_SD_NTSR); |
|---|
| .. | .. |
|---|
| 946 | 951 | |
|---|
| 947 | 952 | static int sunxi_mmc_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) |
|---|
| 948 | 953 | { |
|---|
| 954 | + int ret; |
|---|
| 955 | + |
|---|
| 949 | 956 | /* vqmmc regulator is available */ |
|---|
| 950 | | - if (!IS_ERR(mmc->supply.vqmmc)) |
|---|
| 951 | | - return mmc_regulator_set_vqmmc(mmc, ios); |
|---|
| 957 | + if (!IS_ERR(mmc->supply.vqmmc)) { |
|---|
| 958 | + ret = mmc_regulator_set_vqmmc(mmc, ios); |
|---|
| 959 | + return ret < 0 ? ret : 0; |
|---|
| 960 | + } |
|---|
| 952 | 961 | |
|---|
| 953 | 962 | /* no vqmmc regulator, assume fixed regulator at 3/3.3V */ |
|---|
| 954 | 963 | if (mmc->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) |
|---|
| .. | .. |
|---|
| 1145 | 1154 | .idma_des_size_bits = 16, |
|---|
| 1146 | 1155 | .clk_delays = sunxi_mmc_clk_delays, |
|---|
| 1147 | 1156 | .can_calibrate = false, |
|---|
| 1148 | | - .has_timings_switch = true, |
|---|
| 1157 | + .ccu_has_timings_switch = true, |
|---|
| 1149 | 1158 | }; |
|---|
| 1150 | 1159 | |
|---|
| 1151 | 1160 | static const struct sunxi_mmc_cfg sun9i_a80_cfg = { |
|---|
| .. | .. |
|---|
| 1166 | 1175 | .idma_des_size_bits = 13, |
|---|
| 1167 | 1176 | .clk_delays = NULL, |
|---|
| 1168 | 1177 | .can_calibrate = true, |
|---|
| 1178 | + .needs_new_timings = true, |
|---|
| 1169 | 1179 | }; |
|---|
| 1170 | 1180 | |
|---|
| 1171 | 1181 | static const struct of_device_id sunxi_mmc_of_match[] = { |
|---|
| .. | .. |
|---|
| 1267 | 1277 | if (ret) |
|---|
| 1268 | 1278 | return ret; |
|---|
| 1269 | 1279 | |
|---|
| 1270 | | - host->reg_base = devm_ioremap_resource(&pdev->dev, |
|---|
| 1271 | | - platform_get_resource(pdev, IORESOURCE_MEM, 0)); |
|---|
| 1280 | + host->reg_base = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 1272 | 1281 | if (IS_ERR(host->reg_base)) |
|---|
| 1273 | 1282 | return PTR_ERR(host->reg_base); |
|---|
| 1274 | 1283 | |
|---|
| .. | .. |
|---|
| 1351 | 1360 | goto error_free_host; |
|---|
| 1352 | 1361 | } |
|---|
| 1353 | 1362 | |
|---|
| 1354 | | - if (host->cfg->has_timings_switch) { |
|---|
| 1363 | + if (host->cfg->ccu_has_timings_switch) { |
|---|
| 1355 | 1364 | /* |
|---|
| 1356 | 1365 | * Supports both old and new timing modes. |
|---|
| 1357 | 1366 | * Try setting the clk to new timing mode. |
|---|
| .. | .. |
|---|
| 1385 | 1394 | mmc->f_min = 400000; |
|---|
| 1386 | 1395 | mmc->f_max = 52000000; |
|---|
| 1387 | 1396 | mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | |
|---|
| 1388 | | - MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ; |
|---|
| 1397 | + MMC_CAP_SDIO_IRQ; |
|---|
| 1389 | 1398 | |
|---|
| 1390 | | - if (host->cfg->clk_delays || host->use_new_timings) |
|---|
| 1399 | + /* |
|---|
| 1400 | + * Some H5 devices do not have signal traces precise enough to |
|---|
| 1401 | + * use HS DDR mode for their eMMC chips. |
|---|
| 1402 | + * |
|---|
| 1403 | + * We still enable HS DDR modes for all the other controller |
|---|
| 1404 | + * variants that support them. |
|---|
| 1405 | + */ |
|---|
| 1406 | + if ((host->cfg->clk_delays || host->use_new_timings) && |
|---|
| 1407 | + !of_device_is_compatible(pdev->dev.of_node, |
|---|
| 1408 | + "allwinner,sun50i-h5-emmc")) |
|---|
| 1391 | 1409 | mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR; |
|---|
| 1392 | 1410 | |
|---|
| 1393 | 1411 | ret = mmc_of_parse(mmc); |
|---|
| .. | .. |
|---|
| 1496 | 1514 | static struct platform_driver sunxi_mmc_driver = { |
|---|
| 1497 | 1515 | .driver = { |
|---|
| 1498 | 1516 | .name = "sunxi-mmc", |
|---|
| 1517 | + .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
|---|
| 1499 | 1518 | .of_match_table = of_match_ptr(sunxi_mmc_of_match), |
|---|
| 1500 | 1519 | .pm = &sunxi_mmc_pm_ops, |
|---|
| 1501 | 1520 | }, |
|---|