mmc.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /*
  2. * Copyright (C) 2017 ALLWINNERTECH TECHNOLOGY CO., LTD. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the
  12. * distribution.
  13. * 3. Neither the name of ALLWINNERTECH TECHNOLOGY CO., LTD. nor the names of
  14. * its contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  20. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  21. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  22. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  23. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. #include "hal_def.h"
  30. #include "sdio.h"
  31. #include "sdmmc.h"
  32. #include "hal_sdhost.h"
  33. #include "_sdhost.h"
  34. #include "_mmc.h"
  35. #include "_sd.h"
  36. #ifdef CONFIG_USE_MMC
  37. /*
  38. int32_t mmc_sd_get_csd(struct mmc_card *card) //static
  39. {
  40. struct mmc_command cmd = {0};
  41. uint32_t csd[4] = {0};
  42. cmd.opcode = MMC_SEND_CSD;
  43. cmd.arg = card->rca<<16;
  44. cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
  45. if (mmc_wait_for_cmd(card->host, &cmd)) {
  46. return -1;
  47. }
  48. HAL_Memcpy((void *)csd, (void *)cmd.resp, 16);
  49. //decode CSD reg
  50. card->csd.csd_ver = (csd[3]>>30)&0x3;
  51. card->csd.trans_speed = csd[3]&0xff;
  52. card->csd.read_blk_len = (csd[2]>>16)&0xf;
  53. if (card->type == CT_MMC || card->csd.csd_ver == 0) {
  54. card->csd.c_size_mult = (csd[1]>>15)&0x7;
  55. card->csd.c_size = ((csd[1]>>30)&0x3)|((csd[2]&0x3ff)<<2);
  56. } else {
  57. card->csd.c_size_mult = 0;
  58. card->csd.c_size = ((csd[1]>>16)&0xffff)|((csd[2]&0x3f)<<16);
  59. }
  60. card->csd.cmd_class = (csd[2]>>20)&0xfff;
  61. card->csd.mmc_spec_ver = (csd[3]>>26)&0xf;
  62. return 0;
  63. }
  64. */
  65. int32_t mmc_send_op_cond(struct mmc_card *card, uint32_t ocr, uint32_t *rocr)
  66. {
  67. struct mmc_command cmd = {0};
  68. uint32_t i = 0;
  69. cmd.opcode = MMC_SEND_OP_COND;
  70. cmd.arg = 0;
  71. cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
  72. SD_LOGD("%s,%d arg use ocr?\n", __func__, __LINE__);
  73. do {
  74. if (mmc_wait_for_cmd(card->host, &cmd)) {
  75. return -1;
  76. }
  77. cmd.arg = 0x40000000|(cmd.resp[0]&0xFF8080);
  78. #ifndef SYSTEM_SIMULATION
  79. HAL_MSleep(10);
  80. if (++i == 100)
  81. break;
  82. #else
  83. smc_model_powerup_rdy(card->smc_no);
  84. #endif
  85. } while(!(cmd.resp[0] & 0x80000000));
  86. if (!(cmd.resp[0] & 0x80000000)) {
  87. SD_LOGD("Wait card power up ready timeout, i = %d !\n", i);
  88. return -1;
  89. }
  90. cmd.resp[0] &= 0x7fffffff;
  91. HAL_Memcpy((void *)&card->ocr, (void *)&cmd.resp[0], 4);
  92. SD_LOGD("ocr = %08x !!\n", (unsigned int)cmd.resp[0]);
  93. if (card->ocr.high_capacity) /* bit30 */
  94. mmc_card_set_blockaddr(card);
  95. return 0;
  96. }
  97. static int32_t mmc_public_new_rca(struct mmc_card *card)
  98. {
  99. struct mmc_command cmd = {0};
  100. cmd.opcode = MMC_SET_RELATIVE_ADDR;
  101. cmd.arg = 0x1234 << 16; // why 1234 ??
  102. cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; //different from SD card;
  103. if (mmc_wait_for_cmd(card->host, &cmd)) {
  104. return -1;
  105. }
  106. card->rca = 0x1234;
  107. SD_LOGD("rca = %04x !!\n", (unsigned int)card->rca);
  108. return 0;
  109. }
  110. int32_t mmc_send_extcsd(struct mmc_card *card)
  111. {
  112. struct mmc_command cmd = {0};
  113. struct mmc_data data = {0};
  114. struct mmc_request mrq;
  115. uint8_t extcsd[512] = {0};
  116. struct scatterlist sg = {0};
  117. sg.len = 512;
  118. sg.buffer = extcsd;
  119. cmd.opcode = MMC_SEND_EXT_CSD;
  120. cmd.arg = 0;
  121. cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
  122. cmd.data = &data;
  123. data.blksz = 512;
  124. data.sg_len = 1;
  125. data.sg = &sg;
  126. data.flags = MMC_DATA_READ;
  127. mrq.cmd = &cmd;
  128. mrq.data = &data;
  129. if (mmc_wait_for_req(card->host, &mrq)) {
  130. return -1;
  131. }
  132. SD_LOGD("%s,%d %s\n", __func__, __LINE__, "extcsd");
  133. sd_hex_dump_bytes((void *)extcsd, 512);
  134. //decode EXTCSD
  135. card->extcsd.version = extcsd[192];
  136. card->extcsd.card_type = extcsd[196];
  137. card->extcsd.csd_struc = extcsd[194];
  138. card->extcsd.hs_timing = extcsd[185];
  139. card->extcsd.bus_width = extcsd[183];
  140. if (extcsd[160] & MMC_SWITCH_PART_SUPPORT)
  141. card->extcsd.part_config = extcsd[179];
  142. if (card->extcsd.version >= 3) //>=4.3
  143. card->extcsd.boot_bus_cond = extcsd[177];
  144. return 0;
  145. }
  146. static int32_t mmc_switch_buswidth(struct mmc_card *card, uint32_t width)
  147. {
  148. uint8_t set_val;
  149. int32_t ret = -1;
  150. switch (width) {
  151. case MMC_BUS_WIDTH_1:
  152. set_val = MMC_EXT_CSD_BUS_WIDTH_1;
  153. break;
  154. case MMC_BUS_WIDTH_4:
  155. set_val = MMC_EXT_CSD_BUS_WIDTH_4;
  156. break;
  157. case MMC_BUS_WIDTH_8:
  158. set_val = MMC_EXT_CSD_BUS_WIDTH_8;
  159. break;
  160. default:
  161. set_val = MMC_EXT_CSD_BUS_WIDTH_1;
  162. }
  163. ret = mmc_switch(card, MMC_EXT_CSD_CMD_SET_NORMAL, MMC_EXT_CSD_BUS_WIDTH, set_val);
  164. if (-1 == ret) {
  165. SD_LOGW("Old-MMC Card with 1 bit data only!!\n");
  166. return -1;
  167. }
  168. SD_LOGD("RS-MMC Card!!\n");
  169. card->bus_width = width;
  170. return 0;
  171. }
  172. int32_t mmc_set_buswidth(struct mmc_card *card, uint32_t width)
  173. {
  174. if (card->type == CT_MMC) {
  175. if (card->csd.mmc_spec_ver < MMC_CSD_SPEC_VER_4) {
  176. card->bus_width = width = MMC_BUS_WIDTH_1;
  177. } else if (mmc_switch_buswidth(card, width)) {
  178. SD_LOGD("Set bus width error, use default 1 bit !!\n");
  179. return -1;
  180. }
  181. } else if (card->type == CT_SDSC1x || card->type == CT_SDSC20 || \
  182. card->type == CT_SDHC20 || card->type == CT_SDXC30) {
  183. if (mmc_app_set_bus_width(card, width)) {
  184. SD_LOGD("Set bus width error, use default 1 bit !!\n");
  185. return -1;
  186. }
  187. } else
  188. return -1;
  189. HAL_SDC_Set_BusWidth(card->host, width);
  190. SD_LOGD("Set bus width type: %d !!\n", (unsigned int)width);
  191. return 0;
  192. }
  193. int32_t mmc_switch_part(struct mmc_card *card, uint32_t part_num)
  194. {
  195. return mmc_switch(card, MMC_EXT_CSD_CMD_SET_NORMAL, MMC_EXT_CSD_PART_CONF,
  196. (card->extcsd.part_config & ~MMC_SWITCH_PART_ACCESS_MASK)
  197. | (part_num & MMC_SWITCH_PART_ACCESS_MASK));
  198. }
  199. int32_t mmc_switch_boot_part(struct mmc_card *card, uint32_t boot_ack, uint32_t boot_part)
  200. {
  201. return mmc_switch(card, MMC_EXT_CSD_CMD_SET_NORMAL, MMC_EXT_CSD_PART_CONF,
  202. (card->extcsd.part_config & (~MMC_SWITCH_PART_BOOT_PART_MASK) & (~MMC_SWITCH_PART_BOOT_ACK_MASK))
  203. | ((boot_part << 3) & MMC_SWITCH_PART_BOOT_PART_MASK) | (boot_ack << 6));
  204. }
  205. int32_t mmc_switch_boot_bus_cond(struct mmc_card *card, uint32_t boot_mode, uint32_t rst_bus_cond, uint32_t bus_width)
  206. {
  207. return mmc_switch(card, MMC_EXT_CSD_CMD_SET_NORMAL, MMC_EXT_CSD_BOOT_BUS_COND,
  208. (card->extcsd.boot_bus_cond &
  209. (~MMC_SWITCH_BOOT_MODE_MASK) &
  210. (~MMC_SWITCH_BOOT_RST_BUS_COND_MASK) &
  211. (~MMC_SWITCH_BOOT_BUS_WIDTH_MASK))
  212. | ((boot_mode << 3) & MMC_SWITCH_BOOT_MODE_MASK)
  213. | ((rst_bus_cond << 2) & MMC_SWITCH_BOOT_RST_BUS_COND_MASK)
  214. | ((bus_width) & MMC_SWITCH_BOOT_BUS_WIDTH_MASK) );
  215. }
  216. int32_t smc_model_set_blkcnt(struct mmc_host *host, uint32_t blkcnt)
  217. {
  218. struct mmc_command cmd = {0};
  219. cmd.opcode = MMC_SET_BLOCK_COUNT;
  220. cmd.arg = blkcnt & 0xffff;
  221. cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
  222. if (mmc_wait_for_cmd(host, &cmd)) {
  223. return -1;
  224. }
  225. host->blkcnt = blkcnt;
  226. return 0;
  227. }
  228. int32_t sdmmc_stream_write(struct mmc_card *card, uint32_t blk_num, uint32_t blk_size, uint32_t sg_len, struct scatterlist *sg)
  229. {
  230. struct mmc_command cmd = {0};
  231. struct mmc_data data = {0};
  232. struct mmc_request mrq;
  233. uint32_t status = 0;
  234. if (!card || !card->host) {
  235. SD_LOGE_RAW(ROM_ERR_MASK, "%s,%d err", __func__, __LINE__);
  236. return -1;
  237. }
  238. cmd.opcode = MMC_WRITE_SINGLE_BLOCK;
  239. cmd.arg = blk_num;
  240. if (!mmc_card_blockaddr(card))
  241. cmd.arg <<= 9;
  242. cmd.stop = 0;
  243. cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 |MMC_CMD_ADTC;
  244. cmd.data = &data;
  245. data.flags |= MMC_DATA_WRITE | MMC_DATA_STREAM;
  246. data.blksz = blk_size;
  247. data.sg_len = sg_len;
  248. data.sg = sg;
  249. mrq.cmd = &cmd;
  250. mrq.data = &data;
  251. if (mmc_wait_for_req(card->host, &mrq)) {
  252. return -1;
  253. }
  254. /* check busy */
  255. do {
  256. if (HAL_SDC_Is_Busy(card->host))
  257. continue;
  258. mmc_send_status(card, &status);
  259. } while (!(status & 0x100));
  260. return 0;
  261. }
  262. /*
  263. * Starting point for MMC card init.
  264. */
  265. int mmc_attach_mmc(struct mmc_card *card, struct mmc_host *host)
  266. {
  267. int err;
  268. uint32_t ocr;
  269. uint32_t clk = 400000;
  270. if (!host) {
  271. SD_LOGE_RAW(ROM_ERR_MASK, "%s,%d no host exist!\n", __func__, __LINE__);
  272. return -1;
  273. }
  274. //SD_WARN_ON(!host->claimed);
  275. /* send cmd1 to check MMC */
  276. err = mmc_send_op_cond(card, 0, &ocr);
  277. if (err)
  278. return err;
  279. card->type = CT_MMC;
  280. /* cmd2, send cid */
  281. if (mmc_all_send_cid(host, card->cidno)) {
  282. SD_LOGD("All cards send CID number failed !!\n");
  283. return -1;
  284. } else
  285. SD_LOGD("CID number:%x\n", (unsigned int)card->cidno[0]);
  286. SD_LOGD("%s,%d !!!!!!!@@@@@@@@ called mmc_attach_sd\n", __func__, __LINE__);
  287. /* cmd3, For native busses: get card RCA and quit open drain mode. */
  288. err = mmc_public_new_rca(card);
  289. /* cmd10, get CID register */
  290. if (sdmmc_send_cid(card)) {
  291. SD_LOGW("Card send CID reg failed !!\n");
  292. return -1;
  293. }
  294. /* cmd9, get CSD register */
  295. if (mmc_sd_get_csd(card)) {
  296. SD_LOGW("Card send CSD reg failed !!\n");
  297. return -1;
  298. }
  299. /* cmd7, Select card to standby state, as all following commands rely on that. */
  300. if (mmc_select_card(card, 1)) {
  301. SD_LOGW("mmc_select_card failed !!\n");
  302. return -1;
  303. }
  304. if (card->csd.mmc_spec_ver < MMC_CSD_SPEC_VER_4)
  305. err = 0;
  306. else
  307. err = mmc_send_extcsd(card);
  308. if (err == -1)
  309. return -1;
  310. //sd-acmd6, set buswidth, mmc-cmd6, switch buswidth
  311. if (-1 == sdmmc_set_buswidth(card, 4))
  312. return -1;
  313. mmc_switch_to_high_speed(card);
  314. card->sd_bus_speed = SD_SWITCH_ACCESS_HS_SDR25;
  315. if (card->sd_bus_speed == SD_SWITCH_ACCESS_SDR104)
  316. clk = 208000000;
  317. else if (card->sd_bus_speed == SD_SWITCH_ACCESS_SDR50)
  318. clk = 104000000;
  319. else if (card->sd_bus_speed == SD_SWITCH_ACCESS_HS_SDR25)
  320. clk = 50000000;
  321. else
  322. clk = 25000000;
  323. clk = 50000000;
  324. HAL_SDC_Update_Clk(card->host, clk);
  325. sdmmc_enumerate_card_info(card);
  326. //send tunning pattern
  327. if (card->sd_bus_speed == SD_SWITCH_ACCESS_SDR104 || card->sd_bus_speed == SD_SWITCH_ACCESS_SDR50)
  328. sd_send_tuning_pattern(card);
  329. card->host->card = card;
  330. return err;
  331. }
  332. #endif /* CONFIG_USE_MMC */