mmc.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * This program is free software; you can redistribute it and/or
  3. * modify it under the terms of the GNU General Public License as
  4. * published by the Free Software Foundation; either version 2 of
  5. * the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program; if not, write to the Free Software
  14. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  15. * MA 02111-1307 USA
  16. */
  17. #include <config.h>
  18. #include <common.h>
  19. #include <mmc.h>
  20. #include <asm/errno.h>
  21. #include <asm/arch/hardware.h>
  22. #include <part.h>
  23. #include <fat.h>
  24. #include "mmc_hw.h"
  25. #include <asm/arch/spi.h>
  26. #ifdef CONFIG_MMC
  27. #undef MMC_DEBUG
  28. static block_dev_desc_t mmc_dev;
  29. /* these are filled out by a call to mmc_hw_get_parameters */
  30. static int hw_size; /* in kbytes */
  31. static int hw_nr_sects;
  32. static int hw_sect_size; /* in bytes */
  33. block_dev_desc_t * mmc_get_dev(int dev)
  34. {
  35. return (block_dev_desc_t *)(&mmc_dev);
  36. }
  37. unsigned long mmc_block_read(int dev,
  38. unsigned long start,
  39. lbaint_t blkcnt,
  40. void *buffer)
  41. {
  42. unsigned long rc = 0;
  43. unsigned char *p = (unsigned char *)buffer;
  44. unsigned long i;
  45. unsigned long addr = start;
  46. #ifdef MMC_DEBUG
  47. printf("mmc_block_read: start=%lu, blkcnt=%lu\n", start,
  48. (unsigned long)blkcnt);
  49. #endif
  50. for(i = 0; i < (unsigned long)blkcnt; i++) {
  51. #ifdef MMC_DEBUG
  52. printf("mmc_read_sector: addr=%lu, buffer=%p\n", addr, p);
  53. #endif
  54. (void)mmc_read_sector(addr, p);
  55. rc++;
  56. addr++;
  57. p += hw_sect_size;
  58. }
  59. return rc;
  60. }
  61. /*-----------------------------------------------------------------------------
  62. * Read hardware paramterers (sector size, size, number of sectors)
  63. */
  64. static int mmc_hw_get_parameters(void)
  65. {
  66. unsigned char csddata[16];
  67. unsigned int sizemult;
  68. unsigned int size;
  69. mmc_read_csd(csddata);
  70. hw_sect_size = 1<<(csddata[5] & 0x0f);
  71. size = ((csddata[6]&0x03)<<10)+(csddata[7]<<2)+(csddata[8]&0xc0);
  72. sizemult = ((csddata[10] & 0x80)>>7)+((csddata[9] & 0x03)<<1);
  73. hw_nr_sects = (size+1)*(1<<(sizemult+2));
  74. hw_size = hw_nr_sects*hw_sect_size/1024;
  75. #ifdef MMC_DEBUG
  76. printf("mmc_hw_get_parameters: hw_sect_size=%d, hw_nr_sects=%d, "
  77. "hw_size=%d\n", hw_sect_size, hw_nr_sects, hw_size);
  78. #endif
  79. return 0;
  80. }
  81. int mmc_legacy_init(int verbose)
  82. {
  83. int ret = -ENODEV;
  84. if (verbose)
  85. printf("mmc_legacy_init\n");
  86. spi_init();
  87. /* this meeds to be done twice */
  88. mmc_hw_init();
  89. udelay(1000);
  90. mmc_hw_init();
  91. mmc_hw_get_parameters();
  92. mmc_dev.if_type = IF_TYPE_MMC;
  93. mmc_dev.part_type = PART_TYPE_DOS;
  94. mmc_dev.dev = 0;
  95. mmc_dev.lun = 0;
  96. mmc_dev.type = 0;
  97. mmc_dev.blksz = hw_sect_size;
  98. mmc_dev.lba = hw_nr_sects;
  99. sprintf((char*)mmc_dev.vendor, "Unknown vendor");
  100. sprintf((char*)mmc_dev.product, "Unknown product");
  101. sprintf((char*)mmc_dev.revision, "N/A");
  102. mmc_dev.removable = 0; /* should be true??? */
  103. mmc_dev.block_read = mmc_block_read;
  104. fat_register_device(&mmc_dev, 1);
  105. ret = 0;
  106. return ret;
  107. }
  108. #endif /* CONFIG_MMC */