179c83065SKever Yang /* 279c83065SKever Yang * (C) Copyright 2016 Fuzhou Rockchip Electronics Co., Ltd 379c83065SKever Yang * 479c83065SKever Yang * Rockchip SD Host Controller Interface 579c83065SKever Yang * 679c83065SKever Yang * SPDX-License-Identifier: GPL-2.0+ 779c83065SKever Yang */ 879c83065SKever Yang 979c83065SKever Yang #include <common.h> 1079c83065SKever Yang #include <dm.h> 1179c83065SKever Yang #include <fdtdec.h> 1279c83065SKever Yang #include <libfdt.h> 1379c83065SKever Yang #include <malloc.h> 1479c83065SKever Yang #include <sdhci.h> 1539fbb56fSKever Yang #include <clk.h> 1679c83065SKever Yang 1739fbb56fSKever Yang DECLARE_GLOBAL_DATA_PTR; 1879c83065SKever Yang /* 400KHz is max freq for card ID etc. Use that as min */ 1979c83065SKever Yang #define EMMC_MIN_FREQ 400000 2079c83065SKever Yang 2179c83065SKever Yang struct rockchip_sdhc_plat { 2279c83065SKever Yang struct mmc_config cfg; 2379c83065SKever Yang struct mmc mmc; 2479c83065SKever Yang }; 2579c83065SKever Yang 2679c83065SKever Yang struct rockchip_sdhc { 2779c83065SKever Yang struct sdhci_host host; 2879c83065SKever Yang void *base; 2979c83065SKever Yang }; 3079c83065SKever Yang 3179c83065SKever Yang static int arasan_sdhci_probe(struct udevice *dev) 3279c83065SKever Yang { 3379c83065SKever Yang struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); 3479c83065SKever Yang struct rockchip_sdhc_plat *plat = dev_get_platdata(dev); 3579c83065SKever Yang struct rockchip_sdhc *prv = dev_get_priv(dev); 3679c83065SKever Yang struct sdhci_host *host = &prv->host; 3739fbb56fSKever Yang int max_frequency, ret; 3839fbb56fSKever Yang struct clk clk; 3939fbb56fSKever Yang 4039fbb56fSKever Yang 4139fbb56fSKever Yang max_frequency = fdtdec_get_int(gd->fdt_blob, dev->of_offset, 4239fbb56fSKever Yang "max-frequency", 0); 4339fbb56fSKever Yang ret = clk_get_by_index(dev, 0, &clk); 4439fbb56fSKever Yang if (!ret) { 4539fbb56fSKever Yang ret = clk_set_rate(&clk, max_frequency); 4639fbb56fSKever Yang if (IS_ERR_VALUE(ret)) 4739fbb56fSKever Yang printf("%s clk set rate fail!\n", __func__); 4839fbb56fSKever Yang } else { 4939fbb56fSKever Yang printf("%s fail to get clk\n", __func__); 5039fbb56fSKever Yang } 5179c83065SKever Yang 5279c83065SKever Yang host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD; 53*6d0e34bfSStefan Herbrechtsmeier host->max_clk = max_frequency; 5479c83065SKever Yang 55*6d0e34bfSStefan Herbrechtsmeier ret = sdhci_setup_cfg(&plat->cfg, host, 0, EMMC_MIN_FREQ); 5679c83065SKever Yang 5779c83065SKever Yang host->mmc = &plat->mmc; 5879c83065SKever Yang if (ret) 5979c83065SKever Yang return ret; 6079c83065SKever Yang host->mmc->priv = &prv->host; 6179c83065SKever Yang host->mmc->dev = dev; 6279c83065SKever Yang upriv->mmc = host->mmc; 6379c83065SKever Yang 6479c83065SKever Yang return sdhci_probe(dev); 6579c83065SKever Yang } 6679c83065SKever Yang 6779c83065SKever Yang static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev) 6879c83065SKever Yang { 6979c83065SKever Yang struct sdhci_host *host = dev_get_priv(dev); 7079c83065SKever Yang 7179c83065SKever Yang host->name = dev->name; 7279c83065SKever Yang host->ioaddr = dev_get_addr_ptr(dev); 7379c83065SKever Yang 7479c83065SKever Yang return 0; 7579c83065SKever Yang } 7679c83065SKever Yang 7779c83065SKever Yang static int rockchip_sdhci_bind(struct udevice *dev) 7879c83065SKever Yang { 7979c83065SKever Yang struct rockchip_sdhc_plat *plat = dev_get_platdata(dev); 8079c83065SKever Yang 8124f5aec3SMasahiro Yamada return sdhci_bind(dev, &plat->mmc, &plat->cfg); 8279c83065SKever Yang } 8379c83065SKever Yang 8479c83065SKever Yang static const struct udevice_id arasan_sdhci_ids[] = { 8579c83065SKever Yang { .compatible = "arasan,sdhci-5.1" }, 8679c83065SKever Yang { } 8779c83065SKever Yang }; 8879c83065SKever Yang 8979c83065SKever Yang U_BOOT_DRIVER(arasan_sdhci_drv) = { 9079c83065SKever Yang .name = "arasan_sdhci", 9179c83065SKever Yang .id = UCLASS_MMC, 9279c83065SKever Yang .of_match = arasan_sdhci_ids, 9379c83065SKever Yang .ofdata_to_platdata = arasan_sdhci_ofdata_to_platdata, 9479c83065SKever Yang .ops = &sdhci_ops, 9579c83065SKever Yang .bind = rockchip_sdhci_bind, 9679c83065SKever Yang .probe = arasan_sdhci_probe, 9779c83065SKever Yang .priv_auto_alloc_size = sizeof(struct rockchip_sdhc), 9879c83065SKever Yang .platdata_auto_alloc_size = sizeof(struct rockchip_sdhc_plat), 9979c83065SKever Yang }; 100