1e7ecf7cbSSimon Glass /* 2e7ecf7cbSSimon Glass * Copyright (C) 2015 Google, Inc 3e7ecf7cbSSimon Glass * Written by Simon Glass <sjg@chromium.org> 4e7ecf7cbSSimon Glass * 5e7ecf7cbSSimon Glass * SPDX-License-Identifier: GPL-2.0+ 6e7ecf7cbSSimon Glass */ 7e7ecf7cbSSimon Glass 8e7ecf7cbSSimon Glass #include <common.h> 9e7ecf7cbSSimon Glass #include <mmc.h> 10e7ecf7cbSSimon Glass #include <dm.h> 11e7ecf7cbSSimon Glass #include <dm/lists.h> 12e7ecf7cbSSimon Glass #include <dm/root.h> 13e7ecf7cbSSimon Glass 14e7ecf7cbSSimon Glass struct mmc *mmc_get_mmc_dev(struct udevice *dev) 15e7ecf7cbSSimon Glass { 16e7ecf7cbSSimon Glass struct mmc_uclass_priv *upriv; 17e7ecf7cbSSimon Glass 18e7ecf7cbSSimon Glass if (!device_active(dev)) 19e7ecf7cbSSimon Glass return NULL; 20e7ecf7cbSSimon Glass upriv = dev_get_uclass_priv(dev); 21e7ecf7cbSSimon Glass return upriv->mmc; 22e7ecf7cbSSimon Glass } 23e7ecf7cbSSimon Glass 24*8ef761edSSimon Glass #ifdef CONFIG_BLK 25*8ef761edSSimon Glass struct mmc *find_mmc_device(int dev_num) 26*8ef761edSSimon Glass { 27*8ef761edSSimon Glass struct udevice *dev, *mmc_dev; 28*8ef761edSSimon Glass int ret; 29*8ef761edSSimon Glass 30*8ef761edSSimon Glass ret = blk_get_device(IF_TYPE_MMC, dev_num, &dev); 31*8ef761edSSimon Glass 32*8ef761edSSimon Glass if (ret) { 33*8ef761edSSimon Glass #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) 34*8ef761edSSimon Glass printf("MMC Device %d not found\n", dev_num); 35*8ef761edSSimon Glass #endif 36*8ef761edSSimon Glass return NULL; 37*8ef761edSSimon Glass } 38*8ef761edSSimon Glass 39*8ef761edSSimon Glass mmc_dev = dev_get_parent(dev); 40*8ef761edSSimon Glass 41*8ef761edSSimon Glass return mmc_get_mmc_dev(mmc_dev); 42*8ef761edSSimon Glass } 43*8ef761edSSimon Glass 44*8ef761edSSimon Glass int get_mmc_num(void) 45*8ef761edSSimon Glass { 46*8ef761edSSimon Glass return max(blk_find_max_devnum(IF_TYPE_MMC), 0); 47*8ef761edSSimon Glass } 48*8ef761edSSimon Glass 49*8ef761edSSimon Glass int mmc_get_next_devnum(void) 50*8ef761edSSimon Glass { 51*8ef761edSSimon Glass int ret; 52*8ef761edSSimon Glass 53*8ef761edSSimon Glass ret = get_mmc_num(); 54*8ef761edSSimon Glass if (ret < 0) 55*8ef761edSSimon Glass return ret; 56*8ef761edSSimon Glass 57*8ef761edSSimon Glass return ret + 1; 58*8ef761edSSimon Glass } 59*8ef761edSSimon Glass 60*8ef761edSSimon Glass struct blk_desc *mmc_get_blk_desc(struct mmc *mmc) 61*8ef761edSSimon Glass { 62*8ef761edSSimon Glass struct blk_desc *desc; 63*8ef761edSSimon Glass struct udevice *dev; 64*8ef761edSSimon Glass 65*8ef761edSSimon Glass device_find_first_child(mmc->dev, &dev); 66*8ef761edSSimon Glass if (!dev) 67*8ef761edSSimon Glass return NULL; 68*8ef761edSSimon Glass desc = dev_get_uclass_platdata(dev); 69*8ef761edSSimon Glass 70*8ef761edSSimon Glass return desc; 71*8ef761edSSimon Glass } 72*8ef761edSSimon Glass 73*8ef761edSSimon Glass void mmc_do_preinit(void) 74*8ef761edSSimon Glass { 75*8ef761edSSimon Glass struct udevice *dev; 76*8ef761edSSimon Glass struct uclass *uc; 77*8ef761edSSimon Glass int ret; 78*8ef761edSSimon Glass 79*8ef761edSSimon Glass ret = uclass_get(UCLASS_MMC, &uc); 80*8ef761edSSimon Glass if (ret) 81*8ef761edSSimon Glass return; 82*8ef761edSSimon Glass uclass_foreach_dev(dev, uc) { 83*8ef761edSSimon Glass struct mmc *m = mmc_get_mmc_dev(dev); 84*8ef761edSSimon Glass 85*8ef761edSSimon Glass if (!m) 86*8ef761edSSimon Glass continue; 87*8ef761edSSimon Glass #ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT 88*8ef761edSSimon Glass mmc_set_preinit(m, 1); 89*8ef761edSSimon Glass #endif 90*8ef761edSSimon Glass if (m->preinit) 91*8ef761edSSimon Glass mmc_start_init(m); 92*8ef761edSSimon Glass } 93*8ef761edSSimon Glass } 94*8ef761edSSimon Glass 95*8ef761edSSimon Glass #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) 96*8ef761edSSimon Glass void print_mmc_devices(char separator) 97*8ef761edSSimon Glass { 98*8ef761edSSimon Glass struct udevice *dev; 99*8ef761edSSimon Glass char *mmc_type; 100*8ef761edSSimon Glass bool first = true; 101*8ef761edSSimon Glass 102*8ef761edSSimon Glass for (uclass_first_device(UCLASS_MMC, &dev); 103*8ef761edSSimon Glass dev; 104*8ef761edSSimon Glass uclass_next_device(&dev)) { 105*8ef761edSSimon Glass struct mmc *m = mmc_get_mmc_dev(dev); 106*8ef761edSSimon Glass 107*8ef761edSSimon Glass if (!first) { 108*8ef761edSSimon Glass printf("%c", separator); 109*8ef761edSSimon Glass if (separator != '\n') 110*8ef761edSSimon Glass puts(" "); 111*8ef761edSSimon Glass } 112*8ef761edSSimon Glass if (m->has_init) 113*8ef761edSSimon Glass mmc_type = IS_SD(m) ? "SD" : "eMMC"; 114*8ef761edSSimon Glass else 115*8ef761edSSimon Glass mmc_type = NULL; 116*8ef761edSSimon Glass 117*8ef761edSSimon Glass printf("%s: %d", m->cfg->name, mmc_get_blk_desc(m)->devnum); 118*8ef761edSSimon Glass if (mmc_type) 119*8ef761edSSimon Glass printf(" (%s)", mmc_type); 120*8ef761edSSimon Glass } 121*8ef761edSSimon Glass 122*8ef761edSSimon Glass printf("\n"); 123*8ef761edSSimon Glass } 124*8ef761edSSimon Glass 125*8ef761edSSimon Glass #else 126*8ef761edSSimon Glass void print_mmc_devices(char separator) { } 127*8ef761edSSimon Glass #endif 128*8ef761edSSimon Glass #endif /* CONFIG_BLK */ 129*8ef761edSSimon Glass 130e7ecf7cbSSimon Glass U_BOOT_DRIVER(mmc) = { 131e7ecf7cbSSimon Glass .name = "mmc", 132e7ecf7cbSSimon Glass .id = UCLASS_MMC, 133e7ecf7cbSSimon Glass }; 134e7ecf7cbSSimon Glass 135e7ecf7cbSSimon Glass UCLASS_DRIVER(mmc) = { 136e7ecf7cbSSimon Glass .id = UCLASS_MMC, 137e7ecf7cbSSimon Glass .name = "mmc", 138e7ecf7cbSSimon Glass .flags = DM_UC_FLAG_SEQ_ALIAS, 139e7ecf7cbSSimon Glass .per_device_auto_alloc_size = sizeof(struct mmc_uclass_priv), 140e7ecf7cbSSimon Glass }; 141