uboot/drivers/mmc/rockchip_sdhci.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2016 Fuzhou Rockchip Electronics Co., Ltd
   4 *
   5 * Rockchip SD Host Controller Interface
   6 */
   7
   8#include <common.h>
   9#include <dm.h>
  10#include <dt-structs.h>
  11#include <linux/libfdt.h>
  12#include <malloc.h>
  13#include <mapmem.h>
  14#include <sdhci.h>
  15#include <clk.h>
  16
  17/* 400KHz is max freq for card ID etc. Use that as min */
  18#define EMMC_MIN_FREQ   400000
  19
  20struct rockchip_sdhc_plat {
  21#if CONFIG_IS_ENABLED(OF_PLATDATA)
  22        struct dtd_rockchip_rk3399_sdhci_5_1 dtplat;
  23#endif
  24        struct mmc_config cfg;
  25        struct mmc mmc;
  26};
  27
  28struct rockchip_sdhc {
  29        struct sdhci_host host;
  30        void *base;
  31};
  32
  33static int arasan_sdhci_probe(struct udevice *dev)
  34{
  35        struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
  36        struct rockchip_sdhc_plat *plat = dev_get_platdata(dev);
  37        struct rockchip_sdhc *prv = dev_get_priv(dev);
  38        struct sdhci_host *host = &prv->host;
  39        int max_frequency, ret;
  40        struct clk clk;
  41
  42#if CONFIG_IS_ENABLED(OF_PLATDATA)
  43        struct dtd_rockchip_rk3399_sdhci_5_1 *dtplat = &plat->dtplat;
  44
  45        host->name = dev->name;
  46        host->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
  47        max_frequency = dtplat->max_frequency;
  48        ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &clk);
  49#else
  50        max_frequency = dev_read_u32_default(dev, "max-frequency", 0);
  51        ret = clk_get_by_index(dev, 0, &clk);
  52#endif
  53        if (!ret) {
  54                ret = clk_set_rate(&clk, max_frequency);
  55                if (IS_ERR_VALUE(ret))
  56                        printf("%s clk set rate fail!\n", __func__);
  57        } else {
  58                printf("%s fail to get clk\n", __func__);
  59        }
  60
  61        host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD;
  62        host->max_clk = max_frequency;
  63        /*
  64         * The sdhci-driver only supports 4bit and 8bit, as sdhci_setup_cfg
  65         * doesn't allow us to clear MMC_MODE_4BIT.  Consequently, we don't
  66         * check for other bus-width values.
  67         */
  68        if (host->bus_width == 8)
  69                host->host_caps |= MMC_MODE_8BIT;
  70
  71        ret = sdhci_setup_cfg(&plat->cfg, host, 0, EMMC_MIN_FREQ);
  72
  73        host->mmc = &plat->mmc;
  74        if (ret)
  75                return ret;
  76        host->mmc->priv = &prv->host;
  77        host->mmc->dev = dev;
  78        upriv->mmc = host->mmc;
  79
  80        return sdhci_probe(dev);
  81}
  82
  83static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
  84{
  85#if !CONFIG_IS_ENABLED(OF_PLATDATA)
  86        struct sdhci_host *host = dev_get_priv(dev);
  87
  88        host->name = dev->name;
  89        host->ioaddr = dev_read_addr_ptr(dev);
  90        host->bus_width = dev_read_u32_default(dev, "bus-width", 4);
  91#endif
  92
  93        return 0;
  94}
  95
  96static int rockchip_sdhci_bind(struct udevice *dev)
  97{
  98        struct rockchip_sdhc_plat *plat = dev_get_platdata(dev);
  99
 100        return sdhci_bind(dev, &plat->mmc, &plat->cfg);
 101}
 102
 103static const struct udevice_id arasan_sdhci_ids[] = {
 104        { .compatible = "arasan,sdhci-5.1" },
 105        { }
 106};
 107
 108U_BOOT_DRIVER(arasan_sdhci_drv) = {
 109        .name           = "rockchip_rk3399_sdhci_5_1",
 110        .id             = UCLASS_MMC,
 111        .of_match       = arasan_sdhci_ids,
 112        .ofdata_to_platdata = arasan_sdhci_ofdata_to_platdata,
 113        .ops            = &sdhci_ops,
 114        .bind           = rockchip_sdhci_bind,
 115        .probe          = arasan_sdhci_probe,
 116        .priv_auto_alloc_size = sizeof(struct rockchip_sdhc),
 117        .platdata_auto_alloc_size = sizeof(struct rockchip_sdhc_plat),
 118};
 119