hi6220_dw_mmc.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2015 Linaro
  4. * peter.griffin <peter.griffin@linaro.org>
  5. */
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <dwmmc.h>
  9. #include <errno.h>
  10. #include <fdtdec.h>
  11. #include <malloc.h>
  12. DECLARE_GLOBAL_DATA_PTR;
  13. struct hi6220_dwmmc_plat {
  14. struct mmc_config cfg;
  15. struct mmc mmc;
  16. };
  17. struct hi6220_dwmmc_priv_data {
  18. struct dwmci_host host;
  19. };
  20. struct hisi_mmc_data {
  21. unsigned int clock;
  22. bool use_fifo;
  23. };
  24. static int hi6220_dwmmc_ofdata_to_platdata(struct udevice *dev)
  25. {
  26. struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev);
  27. struct dwmci_host *host = &priv->host;
  28. host->name = dev->name;
  29. host->ioaddr = dev_read_addr_ptr(dev);
  30. host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
  31. "bus-width", 4);
  32. /* use non-removable property for differentiating SD card and eMMC */
  33. if (dev_read_bool(dev, "non-removable"))
  34. host->dev_index = 0;
  35. else
  36. host->dev_index = 1;
  37. host->priv = priv;
  38. return 0;
  39. }
  40. static int hi6220_dwmmc_probe(struct udevice *dev)
  41. {
  42. struct hi6220_dwmmc_plat *plat = dev_get_platdata(dev);
  43. struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
  44. struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev);
  45. struct dwmci_host *host = &priv->host;
  46. struct hisi_mmc_data *mmc_data;
  47. mmc_data = (struct hisi_mmc_data *)dev_get_driver_data(dev);
  48. /* Use default bus speed due to absence of clk driver */
  49. host->bus_hz = mmc_data->clock;
  50. dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, 400000);
  51. host->mmc = &plat->mmc;
  52. host->fifo_mode = mmc_data->use_fifo;
  53. host->mmc->priv = &priv->host;
  54. upriv->mmc = host->mmc;
  55. host->mmc->dev = dev;
  56. return dwmci_probe(dev);
  57. }
  58. static int hi6220_dwmmc_bind(struct udevice *dev)
  59. {
  60. struct hi6220_dwmmc_plat *plat = dev_get_platdata(dev);
  61. int ret;
  62. ret = dwmci_bind(dev, &plat->mmc, &plat->cfg);
  63. if (ret)
  64. return ret;
  65. return 0;
  66. }
  67. static const struct hisi_mmc_data hi3660_mmc_data = {
  68. .clock = 3200000,
  69. .use_fifo = true,
  70. };
  71. static const struct hisi_mmc_data hi6220_mmc_data = {
  72. .clock = 50000000,
  73. .use_fifo = false,
  74. };
  75. static const struct udevice_id hi6220_dwmmc_ids[] = {
  76. { .compatible = "hisilicon,hi6220-dw-mshc",
  77. .data = (ulong)&hi6220_mmc_data },
  78. { .compatible = "hisilicon,hi3798cv200-dw-mshc",
  79. .data = (ulong)&hi6220_mmc_data },
  80. { .compatible = "hisilicon,hi3660-dw-mshc",
  81. .data = (ulong)&hi3660_mmc_data },
  82. { }
  83. };
  84. U_BOOT_DRIVER(hi6220_dwmmc_drv) = {
  85. .name = "hi6220_dwmmc",
  86. .id = UCLASS_MMC,
  87. .of_match = hi6220_dwmmc_ids,
  88. .ofdata_to_platdata = hi6220_dwmmc_ofdata_to_platdata,
  89. .ops = &dm_dwmci_ops,
  90. .bind = hi6220_dwmmc_bind,
  91. .probe = hi6220_dwmmc_probe,
  92. .priv_auto_alloc_size = sizeof(struct hi6220_dwmmc_priv_data),
  93. .platdata_auto_alloc_size = sizeof(struct hi6220_dwmmc_plat),
  94. };