uboot/drivers/mmc/mmc-uclass.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2015 Google, Inc
   4 * Copyright 2020 NXP
   5 * Written by Simon Glass <sjg@chromium.org>
   6 */
   7
   8#define LOG_CATEGORY UCLASS_MMC
   9
  10#include <common.h>
  11#include <log.h>
  12#include <mmc.h>
  13#include <dm.h>
  14#include <dm/device-internal.h>
  15#include <dm/device_compat.h>
  16#include <dm/lists.h>
  17#include <linux/compat.h>
  18#include "mmc_private.h"
  19
  20static int dm_mmc_get_b_max(struct udevice *dev, void *dst, lbaint_t blkcnt)
  21{
  22        struct dm_mmc_ops *ops = mmc_get_ops(dev);
  23        struct mmc *mmc = mmc_get_mmc_dev(dev);
  24
  25        if (ops->get_b_max)
  26                return ops->get_b_max(dev, dst, blkcnt);
  27        else
  28                return mmc->cfg->b_max;
  29}
  30
  31int mmc_get_b_max(struct mmc *mmc, void *dst, lbaint_t blkcnt)
  32{
  33        return dm_mmc_get_b_max(mmc->dev, dst, blkcnt);
  34}
  35
  36static int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
  37                    struct mmc_data *data)
  38{
  39        struct mmc *mmc = mmc_get_mmc_dev(dev);
  40        struct dm_mmc_ops *ops = mmc_get_ops(dev);
  41        int ret;
  42
  43        mmmc_trace_before_send(mmc, cmd);
  44        if (ops->send_cmd)
  45                ret = ops->send_cmd(dev, cmd, data);
  46        else
  47                ret = -ENOSYS;
  48        mmmc_trace_after_send(mmc, cmd, ret);
  49
  50        return ret;
  51}
  52
  53int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
  54{
  55        return dm_mmc_send_cmd(mmc->dev, cmd, data);
  56}
  57
  58static int dm_mmc_set_ios(struct udevice *dev)
  59{
  60        struct dm_mmc_ops *ops = mmc_get_ops(dev);
  61
  62        if (!ops->set_ios)
  63                return -ENOSYS;
  64        return ops->set_ios(dev);
  65}
  66
  67int mmc_set_ios(struct mmc *mmc)
  68{
  69        return dm_mmc_set_ios(mmc->dev);
  70}
  71
  72static int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout_us)
  73{
  74        struct dm_mmc_ops *ops = mmc_get_ops(dev);
  75
  76        if (!ops->wait_dat0)
  77                return -ENOSYS;
  78        return ops->wait_dat0(dev, state, timeout_us);
  79}
  80
  81int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us)
  82{
  83        return dm_mmc_wait_dat0(mmc->dev, state, timeout_us);
  84}
  85
  86static int dm_mmc_get_wp(struct udevice *dev)
  87{
  88        struct dm_mmc_ops *ops = mmc_get_ops(dev);
  89
  90        if (!ops->get_wp)
  91                return -ENOSYS;
  92        return ops->get_wp(dev);
  93}
  94
  95int mmc_getwp(struct mmc *mmc)
  96{
  97        return dm_mmc_get_wp(mmc->dev);
  98}
  99
 100static int dm_mmc_get_cd(struct udevice *dev)
 101{
 102        struct dm_mmc_ops *ops = mmc_get_ops(dev);
 103
 104        if (!ops->get_cd)
 105                return -ENOSYS;
 106        return ops->get_cd(dev);
 107}
 108
 109int mmc_getcd(struct mmc *mmc)
 110{
 111        return dm_mmc_get_cd(mmc->dev);
 112}
 113
 114#ifdef MMC_SUPPORTS_TUNING
 115static int dm_mmc_execute_tuning(struct udevice *dev, uint opcode)
 116{
 117        struct dm_mmc_ops *ops = mmc_get_ops(dev);
 118
 119        if (!ops->execute_tuning)
 120                return -ENOSYS;
 121        return ops->execute_tuning(dev, opcode);
 122}
 123
 124int mmc_execute_tuning(struct mmc *mmc, uint opcode)
 125{
 126        return dm_mmc_execute_tuning(mmc->dev, opcode);
 127}
 128#endif
 129
 130#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
 131static int dm_mmc_set_enhanced_strobe(struct udevice *dev)
 132{
 133        struct dm_mmc_ops *ops = mmc_get_ops(dev);
 134
 135        if (ops->set_enhanced_strobe)
 136                return ops->set_enhanced_strobe(dev);
 137
 138        return -ENOTSUPP;
 139}
 140
 141int mmc_set_enhanced_strobe(struct mmc *mmc)
 142{
 143        return dm_mmc_set_enhanced_strobe(mmc->dev);
 144}
 145#endif
 146
 147static int dm_mmc_hs400_prepare_ddr(struct udevice *dev)
 148{
 149        struct dm_mmc_ops *ops = mmc_get_ops(dev);
 150
 151        if (ops->hs400_prepare_ddr)
 152                return ops->hs400_prepare_ddr(dev);
 153
 154        return 0;
 155}
 156
 157int mmc_hs400_prepare_ddr(struct mmc *mmc)
 158{
 159        return dm_mmc_hs400_prepare_ddr(mmc->dev);
 160}
 161
 162static int dm_mmc_host_power_cycle(struct udevice *dev)
 163{
 164        struct dm_mmc_ops *ops = mmc_get_ops(dev);
 165
 166        if (ops->host_power_cycle)
 167                return ops->host_power_cycle(dev);
 168        return 0;
 169}
 170
 171int mmc_host_power_cycle(struct mmc *mmc)
 172{
 173        return dm_mmc_host_power_cycle(mmc->dev);
 174}
 175
 176static int dm_mmc_deferred_probe(struct udevice *dev)
 177{
 178        struct dm_mmc_ops *ops = mmc_get_ops(dev);
 179
 180        if (ops->deferred_probe)
 181                return ops->deferred_probe(dev);
 182
 183        return 0;
 184}
 185
 186int mmc_deferred_probe(struct mmc *mmc)
 187{
 188        return dm_mmc_deferred_probe(mmc->dev);
 189}
 190
 191static int dm_mmc_reinit(struct udevice *dev)
 192{
 193        struct dm_mmc_ops *ops = mmc_get_ops(dev);
 194
 195        if (ops->reinit)
 196                return ops->reinit(dev);
 197
 198        return 0;
 199}
 200
 201int mmc_reinit(struct mmc *mmc)
 202{
 203        return dm_mmc_reinit(mmc->dev);
 204}
 205
 206int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
 207{
 208        int val;
 209
 210        val = dev_read_u32_default(dev, "bus-width", 1);
 211
 212        switch (val) {
 213        case 0x8:
 214                cfg->host_caps |= MMC_MODE_8BIT;
 215                /* fall through */
 216        case 0x4:
 217                cfg->host_caps |= MMC_MODE_4BIT;
 218                /* fall through */
 219        case 0x1:
 220                cfg->host_caps |= MMC_MODE_1BIT;
 221                break;
 222        default:
 223                dev_err(dev, "Invalid \"bus-width\" value %u!\n", val);
 224                return -EINVAL;
 225        }
 226
 227        /* f_max is obtained from the optional "max-frequency" property */
 228        dev_read_u32(dev, "max-frequency", &cfg->f_max);
 229
 230        if (dev_read_bool(dev, "cap-sd-highspeed"))
 231                cfg->host_caps |= MMC_CAP(SD_HS);
 232        if (dev_read_bool(dev, "cap-mmc-highspeed"))
 233                cfg->host_caps |= MMC_CAP(MMC_HS) | MMC_CAP(MMC_HS_52);
 234        if (dev_read_bool(dev, "sd-uhs-sdr12"))
 235                cfg->host_caps |= MMC_CAP(UHS_SDR12);
 236        if (dev_read_bool(dev, "sd-uhs-sdr25"))
 237                cfg->host_caps |= MMC_CAP(UHS_SDR25);
 238        if (dev_read_bool(dev, "sd-uhs-sdr50"))
 239                cfg->host_caps |= MMC_CAP(UHS_SDR50);
 240        if (dev_read_bool(dev, "sd-uhs-sdr104"))
 241                cfg->host_caps |= MMC_CAP(UHS_SDR104);
 242        if (dev_read_bool(dev, "sd-uhs-ddr50"))
 243                cfg->host_caps |= MMC_CAP(UHS_DDR50);
 244        if (dev_read_bool(dev, "mmc-ddr-1_8v"))
 245                cfg->host_caps |= MMC_CAP(MMC_DDR_52);
 246        if (dev_read_bool(dev, "mmc-ddr-1_2v"))
 247                cfg->host_caps |= MMC_CAP(MMC_DDR_52);
 248        if (dev_read_bool(dev, "mmc-hs200-1_8v"))
 249                cfg->host_caps |= MMC_CAP(MMC_HS_200);
 250        if (dev_read_bool(dev, "mmc-hs200-1_2v"))
 251                cfg->host_caps |= MMC_CAP(MMC_HS_200);
 252        if (dev_read_bool(dev, "mmc-hs400-1_8v"))
 253                cfg->host_caps |= MMC_CAP(MMC_HS_400);
 254        if (dev_read_bool(dev, "mmc-hs400-1_2v"))
 255                cfg->host_caps |= MMC_CAP(MMC_HS_400);
 256        if (dev_read_bool(dev, "mmc-hs400-enhanced-strobe"))
 257                cfg->host_caps |= MMC_CAP(MMC_HS_400_ES);
 258
 259        if (dev_read_bool(dev, "non-removable")) {
 260                cfg->host_caps |= MMC_CAP_NONREMOVABLE;
 261        } else {
 262                if (dev_read_bool(dev, "cd-inverted"))
 263                        cfg->host_caps |= MMC_CAP_CD_ACTIVE_HIGH;
 264                if (dev_read_bool(dev, "broken-cd"))
 265                        cfg->host_caps |= MMC_CAP_NEEDS_POLL;
 266        }
 267
 268        if (dev_read_bool(dev, "no-1-8-v")) {
 269                cfg->host_caps &= ~(UHS_CAPS | MMC_MODE_HS200 |
 270                                    MMC_MODE_HS400 | MMC_MODE_HS400_ES);
 271        }
 272
 273        return 0;
 274}
 275
 276struct mmc *mmc_get_mmc_dev(const struct udevice *dev)
 277{
 278        struct mmc_uclass_priv *upriv;
 279
 280        if (!device_active(dev))
 281                return NULL;
 282        upriv = dev_get_uclass_priv(dev);
 283        return upriv->mmc;
 284}
 285
 286#if CONFIG_IS_ENABLED(BLK)
 287struct mmc *find_mmc_device(int dev_num)
 288{
 289        struct udevice *dev, *mmc_dev;
 290        int ret;
 291
 292        ret = blk_find_device(IF_TYPE_MMC, dev_num, &dev);
 293
 294        if (ret) {
 295#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 296                printf("MMC Device %d not found\n", dev_num);
 297#endif
 298                return NULL;
 299        }
 300
 301        mmc_dev = dev_get_parent(dev);
 302
 303        struct mmc *mmc = mmc_get_mmc_dev(mmc_dev);
 304
 305        return mmc;
 306}
 307
 308int get_mmc_num(void)
 309{
 310        return max((blk_find_max_devnum(IF_TYPE_MMC) + 1), 0);
 311}
 312
 313int mmc_get_next_devnum(void)
 314{
 315        return blk_find_max_devnum(IF_TYPE_MMC);
 316}
 317
 318struct blk_desc *mmc_get_blk_desc(struct mmc *mmc)
 319{
 320        struct blk_desc *desc;
 321        struct udevice *dev;
 322
 323        device_find_first_child(mmc->dev, &dev);
 324        if (!dev)
 325                return NULL;
 326        desc = dev_get_uclass_plat(dev);
 327
 328        return desc;
 329}
 330
 331void mmc_do_preinit(void)
 332{
 333        struct udevice *dev;
 334        struct uclass *uc;
 335        int ret;
 336
 337        ret = uclass_get(UCLASS_MMC, &uc);
 338        if (ret)
 339                return;
 340        uclass_foreach_dev(dev, uc) {
 341                struct mmc *m = mmc_get_mmc_dev(dev);
 342
 343                if (!m)
 344                        continue;
 345
 346                m->user_speed_mode = MMC_MODES_END;  /* Initialising user set speed mode */
 347
 348                if (m->preinit)
 349                        mmc_start_init(m);
 350        }
 351}
 352
 353#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
 354void print_mmc_devices(char separator)
 355{
 356        struct udevice *dev;
 357        char *mmc_type;
 358        bool first = true;
 359
 360        for (uclass_first_device(UCLASS_MMC, &dev);
 361             dev;
 362             uclass_next_device(&dev), first = false) {
 363                struct mmc *m = mmc_get_mmc_dev(dev);
 364
 365                if (!first) {
 366                        printf("%c", separator);
 367                        if (separator != '\n')
 368                                puts(" ");
 369                }
 370                if (m->has_init)
 371                        mmc_type = IS_SD(m) ? "SD" : "eMMC";
 372                else
 373                        mmc_type = NULL;
 374
 375                printf("%s: %d", m->cfg->name, mmc_get_blk_desc(m)->devnum);
 376                if (mmc_type)
 377                        printf(" (%s)", mmc_type);
 378        }
 379
 380        printf("\n");
 381}
 382
 383#else
 384void print_mmc_devices(char separator) { }
 385#endif
 386
 387int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
 388{
 389        struct blk_desc *bdesc;
 390        struct udevice *bdev;
 391        int ret;
 392
 393        if (!mmc_get_ops(dev))
 394                return -ENOSYS;
 395
 396        /* Use the fixed index with aliases node's index */
 397        debug("%s: alias devnum=%d\n", __func__, dev_seq(dev));
 398
 399        ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC,
 400                        dev_seq(dev), 512, 0, &bdev);
 401        if (ret) {
 402                debug("Cannot create block device\n");
 403                return ret;
 404        }
 405        bdesc = dev_get_uclass_plat(bdev);
 406        mmc->cfg = cfg;
 407        mmc->priv = dev;
 408
 409        /* the following chunk was from mmc_register() */
 410
 411        /* Setup dsr related values */
 412        mmc->dsr_imp = 0;
 413        mmc->dsr = 0xffffffff;
 414        /* Setup the universal parts of the block interface just once */
 415        bdesc->removable = 1;
 416
 417        /* setup initial part type */
 418        bdesc->part_type = cfg->part_type;
 419        mmc->dev = dev;
 420        mmc->user_speed_mode = MMC_MODES_END;
 421        return 0;
 422}
 423
 424int mmc_unbind(struct udevice *dev)
 425{
 426        struct udevice *bdev;
 427
 428        device_find_first_child(dev, &bdev);
 429        if (bdev) {
 430                device_remove(bdev, DM_REMOVE_NORMAL);
 431                device_unbind(bdev);
 432        }
 433
 434        return 0;
 435}
 436
 437static int mmc_select_hwpart(struct udevice *bdev, int hwpart)
 438{
 439        struct udevice *mmc_dev = dev_get_parent(bdev);
 440        struct mmc *mmc = mmc_get_mmc_dev(mmc_dev);
 441        struct blk_desc *desc = dev_get_uclass_plat(bdev);
 442        int ret;
 443
 444        if (desc->hwpart == hwpart)
 445                return 0;
 446
 447        if (mmc->part_config == MMCPART_NOAVAILABLE)
 448                return -EMEDIUMTYPE;
 449
 450        ret = mmc_switch_part(mmc, hwpart);
 451        if (!ret)
 452                blkcache_invalidate(desc->if_type, desc->devnum);
 453
 454        return ret;
 455}
 456
 457static int mmc_blk_probe(struct udevice *dev)
 458{
 459        struct udevice *mmc_dev = dev_get_parent(dev);
 460        struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc_dev);
 461        struct mmc *mmc = upriv->mmc;
 462        int ret;
 463
 464        ret = mmc_init(mmc);
 465        if (ret) {
 466                debug("%s: mmc_init() failed (err=%d)\n", __func__, ret);
 467                return ret;
 468        }
 469
 470        return 0;
 471}
 472
 473#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
 474    CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
 475    CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
 476static int mmc_blk_remove(struct udevice *dev)
 477{
 478        struct udevice *mmc_dev = dev_get_parent(dev);
 479        struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc_dev);
 480        struct mmc *mmc = upriv->mmc;
 481
 482        return mmc_deinit(mmc);
 483}
 484#endif
 485
 486static const struct blk_ops mmc_blk_ops = {
 487        .read   = mmc_bread,
 488#if CONFIG_IS_ENABLED(MMC_WRITE)
 489        .write  = mmc_bwrite,
 490        .erase  = mmc_berase,
 491#endif
 492        .select_hwpart  = mmc_select_hwpart,
 493};
 494
 495U_BOOT_DRIVER(mmc_blk) = {
 496        .name           = "mmc_blk",
 497        .id             = UCLASS_BLK,
 498        .ops            = &mmc_blk_ops,
 499        .probe          = mmc_blk_probe,
 500#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
 501    CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
 502    CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
 503        .remove         = mmc_blk_remove,
 504        .flags          = DM_FLAG_OS_PREPARE,
 505#endif
 506};
 507#endif /* CONFIG_BLK */
 508
 509
 510UCLASS_DRIVER(mmc) = {
 511        .id             = UCLASS_MMC,
 512        .name           = "mmc",
 513        .flags          = DM_UC_FLAG_SEQ_ALIAS,
 514        .per_device_auto        = sizeof(struct mmc_uclass_priv),
 515};
 516