mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-14 08:57:58 +00:00
83d290c56f
When U-Boot started using SPDX tags we were among the early adopters and there weren't a lot of other examples to borrow from. So we picked the area of the file that usually had a full license text and replaced it with an appropriate SPDX-License-Identifier: entry. Since then, the Linux Kernel has adopted SPDX tags and they place it as the very first line in a file (except where shebangs are used, then it's second line) and with slightly different comment styles than us. In part due to community overlap, in part due to better tag visibility and in part for other minor reasons, switch over to that style. This commit changes all instances where we have a single declared license in the tag as both the before and after are identical in tag contents. There's also a few places where I found we did not have a tag and have introduced one. Signed-off-by: Tom Rini <trini@konsulko.com>
148 lines
3.7 KiB
C
148 lines
3.7 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Copyright (C) 2017, STMicroelectronics - All Rights Reserved
|
|
* Author(s): Patrice Chotard, <patrice.chotard@st.com> for STMicroelectronics.
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <dm.h>
|
|
#include <mmc.h>
|
|
#include <reset-uclass.h>
|
|
#include <sdhci.h>
|
|
#include <asm/arch/sdhci.h>
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
struct sti_sdhci_plat {
|
|
struct mmc_config cfg;
|
|
struct mmc mmc;
|
|
struct reset_ctl reset;
|
|
int instance;
|
|
};
|
|
|
|
/**
|
|
* sti_mmc_core_config: configure the Arasan HC
|
|
* @dev : udevice
|
|
*
|
|
* Description: this function is to configure the Arasan MMC HC.
|
|
* This should be called when the system starts in case of, on the SoC,
|
|
* it is needed to configure the host controller.
|
|
* This happens on some SoCs, i.e. StiH410, where the MMC0 inside the flashSS
|
|
* needs to be configured as MMC 4.5 to have full capabilities.
|
|
* W/o these settings the SDHCI could configure and use the embedded controller
|
|
* with limited features.
|
|
*/
|
|
static int sti_mmc_core_config(struct udevice *dev)
|
|
{
|
|
struct sti_sdhci_plat *plat = dev_get_platdata(dev);
|
|
struct sdhci_host *host = dev_get_priv(dev);
|
|
int ret;
|
|
|
|
/* only MMC1 has a reset line */
|
|
if (plat->instance) {
|
|
ret = reset_deassert(&plat->reset);
|
|
if (ret < 0) {
|
|
pr_err("MMC1 deassert failed: %d", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
writel(STI_FLASHSS_MMC_CORE_CONFIG_1,
|
|
host->ioaddr + FLASHSS_MMC_CORE_CONFIG_1);
|
|
|
|
if (plat->instance) {
|
|
writel(STI_FLASHSS_MMC_CORE_CONFIG2,
|
|
host->ioaddr + FLASHSS_MMC_CORE_CONFIG_2);
|
|
writel(STI_FLASHSS_MMC_CORE_CONFIG3,
|
|
host->ioaddr + FLASHSS_MMC_CORE_CONFIG_3);
|
|
} else {
|
|
writel(STI_FLASHSS_SDCARD_CORE_CONFIG2,
|
|
host->ioaddr + FLASHSS_MMC_CORE_CONFIG_2);
|
|
writel(STI_FLASHSS_SDCARD_CORE_CONFIG3,
|
|
host->ioaddr + FLASHSS_MMC_CORE_CONFIG_3);
|
|
}
|
|
writel(STI_FLASHSS_MMC_CORE_CONFIG4,
|
|
host->ioaddr + FLASHSS_MMC_CORE_CONFIG_4);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int sti_sdhci_probe(struct udevice *dev)
|
|
{
|
|
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
|
|
struct sti_sdhci_plat *plat = dev_get_platdata(dev);
|
|
struct sdhci_host *host = dev_get_priv(dev);
|
|
int ret;
|
|
|
|
/*
|
|
* identify current mmc instance, mmc1 has a reset, not mmc0
|
|
* MMC0 is wired to the SD slot,
|
|
* MMC1 is wired on the high speed connector
|
|
*/
|
|
ret = reset_get_by_index(dev, 0, &plat->reset);
|
|
if (!ret)
|
|
plat->instance = 1;
|
|
else
|
|
if (ret == -ENOENT)
|
|
plat->instance = 0;
|
|
else
|
|
return ret;
|
|
|
|
ret = sti_mmc_core_config(dev);
|
|
if (ret)
|
|
return ret;
|
|
|
|
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
|
|
SDHCI_QUIRK_32BIT_DMA_ADDR |
|
|
SDHCI_QUIRK_NO_HISPD_BIT;
|
|
|
|
host->host_caps = MMC_MODE_DDR_52MHz;
|
|
|
|
ret = sdhci_setup_cfg(&plat->cfg, host, 50000000, 400000);
|
|
if (ret)
|
|
return ret;
|
|
|
|
host->mmc = &plat->mmc;
|
|
host->mmc->priv = host;
|
|
host->mmc->dev = dev;
|
|
upriv->mmc = host->mmc;
|
|
|
|
return sdhci_probe(dev);
|
|
}
|
|
|
|
static int sti_sdhci_ofdata_to_platdata(struct udevice *dev)
|
|
{
|
|
struct sdhci_host *host = dev_get_priv(dev);
|
|
|
|
host->name = strdup(dev->name);
|
|
host->ioaddr = (void *)devfdt_get_addr(dev);
|
|
|
|
host->bus_width = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
|
|
"bus-width", 4);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int sti_sdhci_bind(struct udevice *dev)
|
|
{
|
|
struct sti_sdhci_plat *plat = dev_get_platdata(dev);
|
|
|
|
return sdhci_bind(dev, &plat->mmc, &plat->cfg);
|
|
}
|
|
|
|
static const struct udevice_id sti_sdhci_ids[] = {
|
|
{ .compatible = "st,sdhci" },
|
|
{ }
|
|
};
|
|
|
|
U_BOOT_DRIVER(sti_mmc) = {
|
|
.name = "sti_sdhci",
|
|
.id = UCLASS_MMC,
|
|
.of_match = sti_sdhci_ids,
|
|
.bind = sti_sdhci_bind,
|
|
.ops = &sdhci_ops,
|
|
.ofdata_to_platdata = sti_sdhci_ofdata_to_platdata,
|
|
.probe = sti_sdhci_probe,
|
|
.priv_auto_alloc_size = sizeof(struct sdhci_host),
|
|
.platdata_auto_alloc_size = sizeof(struct sti_sdhci_plat),
|
|
};
|