1 /* 2 * Copyright (C) 2015 Google, Inc 3 * Written by Simon Glass <sjg@chromium.org> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <mmc.h> 10 #include <dm.h> 11 #include <dm/device-internal.h> 12 #include <dm/lists.h> 13 #include <dm/root.h> 14 #include "mmc_private.h" 15 16 DECLARE_GLOBAL_DATA_PTR; 17 18 int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, 19 struct mmc_data *data) 20 { 21 struct mmc *mmc = mmc_get_mmc_dev(dev); 22 struct dm_mmc_ops *ops = mmc_get_ops(dev); 23 int ret; 24 25 mmmc_trace_before_send(mmc, cmd); 26 if (ops->send_cmd) 27 ret = ops->send_cmd(dev, cmd, data); 28 else 29 ret = -ENOSYS; 30 mmmc_trace_after_send(mmc, cmd, ret); 31 32 if (ret && cmd->cmdidx != SD_CMD_SEND_IF_COND 33 && cmd->cmdidx != MMC_CMD_APP_CMD) 34 printf("MMC error: The cmd index is %d, ret is %d\n", cmd->cmdidx, ret); 35 36 return ret; 37 } 38 39 #ifdef CONFIG_SPL_BLK_READ_PREPARE 40 int dm_mmc_send_cmd_prepare(struct udevice *dev, struct mmc_cmd *cmd, 41 struct mmc_data *data) 42 { 43 struct mmc *mmc = mmc_get_mmc_dev(dev); 44 struct dm_mmc_ops *ops = mmc_get_ops(dev); 45 int ret; 46 47 mmmc_trace_before_send(mmc, cmd); 48 if (ops->send_cmd_prepare) 49 ret = ops->send_cmd_prepare(dev, cmd, data); 50 else 51 ret = -ENOSYS; 52 mmmc_trace_after_send(mmc, cmd, ret); 53 if (ret && cmd->cmdidx != SD_CMD_SEND_IF_COND 54 && cmd->cmdidx != MMC_CMD_APP_CMD) 55 printf("MMC error: The cmd index is %d, ret is %d\n", cmd->cmdidx, ret); 56 57 return ret; 58 } 59 #endif 60 61 int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) 62 { 63 return dm_mmc_send_cmd(mmc->dev, cmd, data); 64 } 65 66 #ifdef CONFIG_SPL_BLK_READ_PREPARE 67 int mmc_send_cmd_prepare(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) 68 { 69 return dm_mmc_send_cmd_prepare(mmc->dev, cmd, data); 70 } 71 #endif 72 73 bool mmc_card_busy(struct mmc *mmc) 74 { 75 struct dm_mmc_ops *ops = mmc_get_ops(mmc->dev); 76 77 if (!ops->card_busy) 78 return -ENOSYS; 79 return ops->card_busy(mmc->dev); 80 } 81 82 bool mmc_can_card_busy(struct mmc *mmc) 83 { 84 struct dm_mmc_ops *ops = mmc_get_ops(mmc->dev); 85 86 return !!ops->card_busy; 87 } 88 89 int dm_mmc_set_ios(struct udevice *dev) 90 { 91 struct dm_mmc_ops *ops = mmc_get_ops(dev); 92 93 if (!ops->set_ios) 94 return -ENOSYS; 95 return ops->set_ios(dev); 96 } 97 98 int mmc_set_ios(struct mmc *mmc) 99 { 100 return dm_mmc_set_ios(mmc->dev); 101 } 102 103 int dm_mmc_get_wp(struct udevice *dev) 104 { 105 struct dm_mmc_ops *ops = mmc_get_ops(dev); 106 107 if (!ops->get_wp) 108 return -ENOSYS; 109 return ops->get_wp(dev); 110 } 111 112 int mmc_getwp(struct mmc *mmc) 113 { 114 return dm_mmc_get_wp(mmc->dev); 115 } 116 117 int dm_mmc_get_cd(struct udevice *dev) 118 { 119 struct dm_mmc_ops *ops = mmc_get_ops(dev); 120 121 if (!ops->get_cd) 122 return -ENOSYS; 123 return ops->get_cd(dev); 124 } 125 126 int mmc_getcd(struct mmc *mmc) 127 { 128 return dm_mmc_get_cd(mmc->dev); 129 } 130 131 struct mmc *mmc_get_mmc_dev(struct udevice *dev) 132 { 133 struct mmc_uclass_priv *upriv; 134 135 if (!device_active(dev)) 136 return NULL; 137 upriv = dev_get_uclass_priv(dev); 138 return upriv->mmc; 139 } 140 141 #if CONFIG_IS_ENABLED(BLK) 142 struct mmc *find_mmc_device(int dev_num) 143 { 144 struct udevice *dev, *mmc_dev; 145 int ret; 146 147 ret = blk_find_device(IF_TYPE_MMC, dev_num, &dev); 148 149 if (ret) { 150 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) 151 printf("MMC Device %d not found\n", dev_num); 152 #endif 153 return NULL; 154 } 155 156 mmc_dev = dev_get_parent(dev); 157 158 struct mmc *mmc = mmc_get_mmc_dev(mmc_dev); 159 160 return mmc; 161 } 162 163 int get_mmc_num(void) 164 { 165 return max((blk_find_max_devnum(IF_TYPE_MMC) + 1), 0); 166 } 167 168 int mmc_get_next_devnum(void) 169 { 170 return blk_find_max_devnum(IF_TYPE_MMC); 171 } 172 173 struct blk_desc *mmc_get_blk_desc(struct mmc *mmc) 174 { 175 struct blk_desc *desc; 176 struct udevice *dev; 177 178 device_find_first_child(mmc->dev, &dev); 179 if (!dev) 180 return NULL; 181 desc = dev_get_uclass_platdata(dev); 182 183 return desc; 184 } 185 186 void mmc_do_preinit(void) 187 { 188 struct udevice *dev; 189 struct uclass *uc; 190 int ret; 191 192 ret = uclass_get(UCLASS_MMC, &uc); 193 if (ret) 194 return; 195 uclass_foreach_dev(dev, uc) { 196 struct mmc *m = mmc_get_mmc_dev(dev); 197 198 if (!m) 199 continue; 200 #ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT 201 mmc_set_preinit(m, 1); 202 #endif 203 if (m->preinit) 204 mmc_start_init(m); 205 } 206 } 207 208 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) 209 void print_mmc_devices(char separator) 210 { 211 struct udevice *dev; 212 char *mmc_type; 213 bool first = true; 214 215 for (uclass_first_device(UCLASS_MMC, &dev); 216 dev; 217 uclass_next_device(&dev), first = false) { 218 struct mmc *m = mmc_get_mmc_dev(dev); 219 220 if (!first) { 221 printf("%c", separator); 222 if (separator != '\n') 223 puts(" "); 224 } 225 if (m->has_init) 226 mmc_type = IS_SD(m) ? "SD" : "eMMC"; 227 else 228 mmc_type = NULL; 229 230 printf("%s: %d", m->cfg->name, mmc_get_blk_desc(m)->devnum); 231 if (mmc_type) 232 printf(" (%s)", mmc_type); 233 } 234 235 printf("\n"); 236 } 237 238 #else 239 void print_mmc_devices(char separator) { } 240 #endif 241 242 int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg) 243 { 244 struct blk_desc *bdesc; 245 struct udevice *bdev; 246 int ret, devnum = -1; 247 248 if (!mmc_get_ops(dev)) 249 return -ENOSYS; 250 /* Use the fixed index with aliase node's index */ 251 ret = dev_read_alias_seq(dev, &devnum); 252 debug("%s: alias ret=%d, devnum=%d\n", __func__, ret, devnum); 253 254 ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC, 255 devnum, 512, 0, &bdev); 256 if (ret) { 257 debug("Cannot create block device\n"); 258 return ret; 259 } 260 bdesc = dev_get_uclass_platdata(bdev); 261 mmc->cfg = cfg; 262 mmc->priv = dev; 263 264 /* the following chunk was from mmc_register() */ 265 266 /* Setup dsr related values */ 267 mmc->dsr_imp = 0; 268 mmc->dsr = 0xffffffff; 269 /* Setup the universal parts of the block interface just once */ 270 bdesc->removable = 1; 271 272 /* setup initial part type */ 273 bdesc->part_type = cfg->part_type; 274 mmc->dev = dev; 275 276 return 0; 277 } 278 279 int mmc_unbind(struct udevice *dev) 280 { 281 struct udevice *bdev; 282 283 device_find_first_child(dev, &bdev); 284 if (bdev) { 285 device_remove(bdev, DM_REMOVE_NORMAL); 286 device_unbind(bdev); 287 } 288 289 return 0; 290 } 291 292 static int mmc_select_hwpart(struct udevice *bdev, int hwpart) 293 { 294 struct udevice *mmc_dev = dev_get_parent(bdev); 295 struct mmc *mmc = mmc_get_mmc_dev(mmc_dev); 296 struct blk_desc *desc = dev_get_uclass_platdata(bdev); 297 298 if (desc->hwpart == hwpart) 299 return 0; 300 301 if (mmc->part_config == MMCPART_NOAVAILABLE) 302 return -EMEDIUMTYPE; 303 304 return mmc_switch_part(mmc, hwpart); 305 } 306 307 static int mmc_blk_probe(struct udevice *dev) 308 { 309 struct udevice *mmc_dev = dev_get_parent(dev); 310 struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc_dev); 311 struct mmc *mmc = upriv->mmc; 312 int ret; 313 314 ret = mmc_init(mmc); 315 if (ret) { 316 debug("%s: mmc_init() failed (err=%d)\n", __func__, ret); 317 return ret; 318 } 319 320 return 0; 321 } 322 323 static const struct blk_ops mmc_blk_ops = { 324 .read = mmc_bread, 325 #if CONFIG_IS_ENABLED(MMC_WRITE) 326 .write = mmc_bwrite, 327 .erase = mmc_berase, 328 #endif 329 .select_hwpart = mmc_select_hwpart, 330 }; 331 332 U_BOOT_DRIVER(mmc_blk) = { 333 .name = "mmc_blk", 334 .id = UCLASS_BLK, 335 .ops = &mmc_blk_ops, 336 .probe = mmc_blk_probe, 337 }; 338 #endif /* CONFIG_BLK */ 339 340 U_BOOT_DRIVER(mmc) = { 341 .name = "mmc", 342 .id = UCLASS_MMC, 343 }; 344 345 UCLASS_DRIVER(mmc) = { 346 .id = UCLASS_MMC, 347 .name = "mmc", 348 .flags = DM_UC_FLAG_SEQ_ALIAS, 349 .per_device_auto_alloc_size = sizeof(struct mmc_uclass_priv), 350 }; 351