mmc_hw.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. This code was original written by Ulrich Radig and modified by
  3. Embedded Artists AB (www.embeddedartists.com).
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  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, MA 02111-1307 USA
  15. */
  16. #include <config.h>
  17. #include <common.h>
  18. #include <asm/arch/hardware.h>
  19. #include <asm/arch/spi.h>
  20. #define MMC_Enable() PUT32(IO1CLR, 1l << 22)
  21. #define MMC_Disable() PUT32(IO1SET, 1l << 22)
  22. #define mmc_spi_cfg() spi_set_clock(8); spi_set_cfg(0, 1, 0);
  23. static unsigned char Write_Command_MMC (unsigned char *CMD);
  24. static void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer,
  25. unsigned short int Bytes);
  26. /* initialize the hardware */
  27. int mmc_hw_init(void)
  28. {
  29. unsigned long a;
  30. unsigned short int Timeout = 0;
  31. unsigned char b;
  32. unsigned char CMD[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95};
  33. /* set-up GPIO and SPI */
  34. (*((volatile unsigned long *)PINSEL2)) &= ~(1l << 3); /* clear bit 3 */
  35. (*((volatile unsigned long *)IO1DIR)) |= (1l << 22); /* set bit 22 (output) */
  36. MMC_Disable();
  37. spi_lock();
  38. spi_set_clock(248);
  39. spi_set_cfg(0, 1, 0);
  40. MMC_Enable();
  41. /* waste some time */
  42. for(a=0; a < 20000; a++)
  43. asm("nop");
  44. /* Put the MMC/SD-card into SPI-mode */
  45. for (b = 0; b < 10; b++) /* Sends min 74+ clocks to the MMC/SD-card */
  46. spi_write(0xff);
  47. /* Sends command CMD0 to MMC/SD-card */
  48. while (Write_Command_MMC(CMD) != 1) {
  49. if (Timeout++ > 200) {
  50. MMC_Disable();
  51. spi_unlock();
  52. return(1); /* Abort with command 1 (return 1) */
  53. }
  54. }
  55. /* Sends Command CMD1 an MMC/SD-card */
  56. Timeout = 0;
  57. CMD[0] = 0x41;/* Command 1 */
  58. CMD[5] = 0xFF;
  59. while (Write_Command_MMC(CMD) != 0) {
  60. if (Timeout++ > 200) {
  61. MMC_Disable();
  62. spi_unlock();
  63. return (2); /* Abort with command 2 (return 2) */
  64. }
  65. }
  66. MMC_Disable();
  67. spi_unlock();
  68. return 0;
  69. }
  70. /* ############################################################################
  71. Sends a command to the MMC/SD-card
  72. ######################################################################### */
  73. static unsigned char Write_Command_MMC (unsigned char *CMD)
  74. {
  75. unsigned char a, tmp = 0xff;
  76. unsigned short int Timeout = 0;
  77. MMC_Disable();
  78. spi_write(0xFF);
  79. MMC_Enable();
  80. for (a = 0; a < 0x06; a++)
  81. spi_write(*CMD++);
  82. while (tmp == 0xff) {
  83. tmp = spi_read();
  84. if (Timeout++ > 5000)
  85. break;
  86. }
  87. return (tmp);
  88. }
  89. /* ############################################################################
  90. Routine to read the CID register from the MMC/SD-card (16 bytes)
  91. ######################################################################### */
  92. void MMC_Read_Block(unsigned char *CMD, unsigned char *Buffer, unsigned short
  93. int Bytes)
  94. {
  95. unsigned short int a;
  96. spi_lock();
  97. mmc_spi_cfg();
  98. MMC_Enable();
  99. if (Write_Command_MMC(CMD) != 0) {
  100. MMC_Disable();
  101. spi_unlock();
  102. return;
  103. }
  104. while (spi_read() != 0xfe) {};
  105. for (a = 0; a < Bytes; a++)
  106. *Buffer++ = spi_read();
  107. /* Read the CRC-byte */
  108. spi_read(); /* CRC - byte is discarded */
  109. spi_read(); /* CRC - byte is discarded */
  110. /* set MMC_Chip_Select to high (MMC/SD-card Inaktiv) */
  111. MMC_Disable();
  112. spi_unlock();
  113. return;
  114. }
  115. /* ############################################################################
  116. Routine to read a block (512 bytes) from the MMC/SD-card
  117. ######################################################################### */
  118. unsigned char mmc_read_sector (unsigned long addr,unsigned char *Buffer)
  119. {
  120. /* Command 16 to read aBlocks from the MMC/SD - caed */
  121. unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
  122. /* The address on the MMC/SD-card is in bytes,
  123. addr is transformed from blocks to bytes and the result is
  124. placed into the command */
  125. addr = addr << 9; /* addr = addr * 512 */
  126. CMD[1] = ((addr & 0xFF000000) >> 24);
  127. CMD[2] = ((addr & 0x00FF0000) >> 16);
  128. CMD[3] = ((addr & 0x0000FF00) >> 8 );
  129. MMC_Read_Block(CMD, Buffer, 512);
  130. return (0);
  131. }
  132. /* ############################################################################
  133. Routine to write a block (512 byte) to the MMC/SD-card
  134. ######################################################################### */
  135. unsigned char mmc_write_sector (unsigned long addr,unsigned char *Buffer)
  136. {
  137. unsigned char tmp, a;
  138. unsigned short int b;
  139. /* Command 24 to write a block to the MMC/SD - card */
  140. unsigned char CMD[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF};
  141. /* The address on the MMC/SD-card is in bytes,
  142. addr is transformed from blocks to bytes and the result is
  143. placed into the command */
  144. addr = addr << 9; /* addr = addr * 512 */
  145. CMD[1] = ((addr & 0xFF000000) >> 24);
  146. CMD[2] = ((addr & 0x00FF0000) >> 16);
  147. CMD[3] = ((addr & 0x0000FF00) >> 8 );
  148. spi_lock();
  149. mmc_spi_cfg();
  150. MMC_Enable();
  151. /* Send command CMD24 to the MMC/SD-card (Write 1 Block/512 Bytes) */
  152. tmp = Write_Command_MMC(CMD);
  153. if (tmp != 0) {
  154. MMC_Disable();
  155. spi_unlock();
  156. return(tmp);
  157. }
  158. /* Do a short delay and send a clock-pulse to the MMC/SD-card */
  159. for (a = 0; a < 100; a++)
  160. spi_read();
  161. /* Send a start byte to the MMC/SD-card */
  162. spi_write(0xFE);
  163. /* Write the block (512 bytes) to the MMC/SD-card */
  164. for (b = 0; b < 512; b++)
  165. spi_write(*Buffer++);
  166. /* write the CRC-Byte */
  167. spi_write(0xFF); /* write a dummy CRC */
  168. spi_write(0xFF); /* CRC code is not used */
  169. /* Wait for MMC/SD-card busy */
  170. while (spi_read() != 0xff) {};
  171. /* set MMC_Chip_Select to high (MMC/SD-card inactive) */
  172. MMC_Disable();
  173. spi_unlock();
  174. return (0);
  175. }
  176. /* #########################################################################
  177. Routine to read the CSD register from the MMC/SD-card (16 bytes)
  178. ######################################################################### */
  179. unsigned char mmc_read_csd (unsigned char *Buffer)
  180. {
  181. /* Command to read the CSD register */
  182. unsigned char CMD[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0xFF};
  183. MMC_Read_Block(CMD, Buffer, 16);
  184. return (0);
  185. }