/* * There is no requirement to disable the internal clock before * changing the SD clock configuration. Moreover, disabling the * internal clock, changing the configuration and re-enabling the * internal clock causes some bugs. It can prevent to get the internal * clock stable flag ready and an unexpected switch to the base clock * when using presets.
*/
clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
clk &= SDHCI_CLOCK_INT_EN;
sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
dev_dbg(dev, "update clk mul to %u as gck rate is %u Hz and clk base is %u Hz\n",
clk_mul, gck_rate, clk_base_rate);
/* * We have to set preset values because it depends on the clk_mul * value. Moreover, SDR104 is supported in a degraded mode since the * maximum sd clock value is 120 MHz instead of 208 MHz. For that * reason, we need to use presets to support SDR104.
*/
preset_div = DIV_ROUND_UP(gck_rate, 24000000) - 1;
writew(SDHCI_AT91_PRESET_COMMON_CONF | preset_div,
host->ioaddr + SDHCI_PRESET_FOR_SDR12);
preset_div = DIV_ROUND_UP(gck_rate, 50000000) - 1;
writew(SDHCI_AT91_PRESET_COMMON_CONF | preset_div,
host->ioaddr + SDHCI_PRESET_FOR_SDR25);
preset_div = DIV_ROUND_UP(gck_rate, 100000000) - 1;
writew(SDHCI_AT91_PRESET_COMMON_CONF | preset_div,
host->ioaddr + SDHCI_PRESET_FOR_SDR50);
preset_div = DIV_ROUND_UP(gck_rate, 120000000) - 1;
writew(SDHCI_AT91_PRESET_COMMON_CONF | preset_div,
host->ioaddr + SDHCI_PRESET_FOR_SDR104);
preset_div = DIV_ROUND_UP(gck_rate, 50000000) - 1;
writew(SDHCI_AT91_PRESET_COMMON_CONF | preset_div,
host->ioaddr + SDHCI_PRESET_FOR_DDR50);
priv->mainck = devm_clk_get(&pdev->dev, "baseclk"); if (IS_ERR(priv->mainck)) { if (soc_data->baseclk_is_generated_internally)
priv->mainck = NULL; else return dev_err_probe(&pdev->dev, PTR_ERR(priv->mainck), "failed to get baseclk\n");
}
priv->hclock = devm_clk_get(&pdev->dev, "hclock"); if (IS_ERR(priv->hclock)) return dev_err_probe(&pdev->dev, PTR_ERR(priv->hclock), "failed to get hclock\n");
priv->gck = devm_clk_get(&pdev->dev, "multclk"); if (IS_ERR(priv->gck)) return dev_err_probe(&pdev->dev, PTR_ERR(priv->gck), "failed to get multclk\n");
ret = sdhci_at91_set_clks_presets(&pdev->dev); if (ret) return ret;
priv->restore_needed = false;
/* * if SDCAL pin is wrongly connected, we must enable * the analog calibration cell permanently.
*/
priv->cal_always_on =
device_property_read_bool(&pdev->dev, "microchip,sdcal-inverted");
ret = mmc_of_parse(host->mmc); if (ret) goto clocks_disable_unprepare;
/* HS200 is broken at this moment */
host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200;
ret = sdhci_add_host(host); if (ret) goto pm_runtime_disable;
/* * When calling sdhci_runtime_suspend_host(), the sdhci layer makes * the assumption that all the clocks of the controller are disabled. * It means we can't get irq from it when it is runtime suspended. * For that reason, it is not planned to wake-up on a card detect irq * from the controller. * If we want to use runtime PM and to be able to wake-up on card * insertion, we have to use a GPIO for the card detection or we can * use polling. Be aware that using polling will resume/suspend the * controller between each attempt. * Disable SDHCI_QUIRK_BROKEN_CARD_DETECTION to be sure nobody tries * to enable polling via device tree with broken-cd property.
*/ if (mmc_card_is_removable(host->mmc) &&
mmc_gpio_get_cd(host->mmc) < 0) {
host->mmc->caps |= MMC_CAP_NEEDS_POLL;
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
}
/* * If the device attached to the MMC bus is not removable, it is safer * to set the Force Card Detect bit. People often don't connect the * card detect signal and use this pin for another purpose. If the card * detect pin is not muxed to SDHCI controller, a default value is * used. This value can be different from a SoC revision to another * one. Problems come when this default value is not card present. To * avoid this case, if the device is non removable then the card * detection procedure using the SDMCC_CD signal is bypassed. * This bit is reset when a software reset for all command is performed * so we need to implement our own reset function to set back this bit. * * WA: SAMA5D2 doesn't drive CMD if using CD GPIO line.
*/ if ((host->mmc->caps & MMC_CAP_NONREMOVABLE)
|| mmc_gpio_get_cd(host->mmc) >= 0)
sdhci_at91_set_force_card_detect(host);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.