mmc_common_inter.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein is
  5. * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
  6. * the prior written permission of MediaTek inc. and/or its licensors, any
  7. * reproduction, modification, use or disclosure of MediaTek Software, and
  8. * information contained herein, in whole or in part, shall be strictly
  9. * prohibited.
  10. *
  11. * MediaTek Inc. (C) 2010. All rights reserved.
  12. *
  13. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  14. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  15. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
  16. * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
  17. * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  19. * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
  20. * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
  21. * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
  22. * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
  23. * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
  24. * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
  25. * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
  26. * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  27. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
  28. * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
  29. * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
  30. * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
  31. * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  32. *
  33. * The following software/firmware and/or related documentation ("MediaTek
  34. * Software") have been modified by MediaTek Inc. All revisions are subject to
  35. * any receiver's applicable license agreements with MediaTek Inc.
  36. */
  37. #include "msdc_cfg.h" //Include msdc_cfg.h for defining MMC_MSDC_DRV_PRELOADER
  38. #if !defined(MMC_MSDC_DRV_CTP) // CTP no need this file
  39. #include "addr_trans.h"
  40. #include "msdc.h"
  41. #define MMC_HOST_ID 0
  42. #define BUF_BLK_NUM 4 /* 4 * 512bytes = 2KB */
  43. /**************************************************************************
  44. * DEBUG CONTROL
  45. **************************************************************************/
  46. /**************************************************************************
  47. * MACRO DEFINITION
  48. **************************************************************************/
  49. /**************************************************************************
  50. * EXTERNAL DECLARATION
  51. **************************************************************************/
  52. static addr_trans_info_t g_emmc_addr_trans[EMMC_PART_END];
  53. static addr_trans_tbl_t g_addr_trans_tbl;
  54. int mmc_do_erase(int dev_num,u64 start_addr,u64 len,u32 part_id);
  55. #if defined(MMC_MSDC_DRV_PRELOADER)
  56. extern struct nand_chip g_nand_chip;
  57. static blkdev_t g_mmc_bdev;
  58. #endif
  59. #if defined(MMC_MSDC_DRV_LK)
  60. int g_user_virt_addr=0;
  61. #endif
  62. u64 g_emmc_size = 0;
  63. u64 g_emmc_user_size = 0;
  64. int mmc_switch_part(u32 part_id)
  65. {
  66. int err = MMC_ERR_NONE;
  67. struct mmc_card *card;
  68. struct mmc_host *host;
  69. u8 part = (u8)part_id;
  70. u8 cfg;
  71. u8 *ext_csd;
  72. card = mmc_get_card(MMC_HOST_ID);
  73. host = mmc_get_host(MMC_HOST_ID);
  74. if (!card)
  75. return MMC_ERR_INVALID;
  76. ext_csd = &card->raw_ext_csd[0];
  77. if (mmc_card_mmc(card) && ext_csd[EXT_CSD_REV] >= 3) {
  78. if (part_id == EMMC_PART_USER)
  79. part = EXT_CSD_PART_CFG_DEFT_PART;
  80. else if(part_id == EMMC_PART_BOOT1)
  81. part = EXT_CSD_PART_CFG_BOOT_PART_1;
  82. else if(part_id == EMMC_PART_BOOT2)
  83. part = EXT_CSD_PART_CFG_BOOT_PART_2;
  84. cfg = card->raw_ext_csd[EXT_CSD_PART_CFG];
  85. /* already set to specific partition */
  86. if (part == (cfg & 0x7))
  87. return MMC_ERR_NONE;
  88. cfg = (cfg & ~0x7) | part;
  89. err = mmc_switch(host, card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CFG, cfg);
  90. if (err == MMC_ERR_NONE) {
  91. err = mmc_read_ext_csd(host, card);
  92. if (err == MMC_ERR_NONE) {
  93. ext_csd = &card->raw_ext_csd[0];
  94. if (ext_csd[EXT_CSD_PART_CFG] != cfg)
  95. err = MMC_ERR_FAILED;
  96. }
  97. }
  98. }
  99. if (err)
  100. MSG(ERR, "[%s]: failed to switch part_id:%d, part:%d, err=%d\n", __func__, part_id, part, err);
  101. return err;
  102. }
  103. #if defined(MMC_MSDC_DRV_PRELOADER)
  104. static int mmc_addr_trans_tbl_init(struct mmc_card *card, blkdev_t *bdev)
  105. #elif defined(MMC_MSDC_DRV_LK)
  106. static int mmc_addr_trans_tbl_init(struct mmc_card *card)
  107. #endif
  108. {
  109. u32 wpg_sz;
  110. u8 *ext_csd;
  111. memset(&g_addr_trans_tbl, 0, sizeof(addr_trans_tbl_t));
  112. ext_csd = &card->raw_ext_csd[0];
  113. #if defined(MMC_MSDC_DRV_PRELOADER)
  114. bdev->offset = 0;
  115. #endif
  116. if (mmc_card_mmc(card) && ext_csd[EXT_CSD_REV] >= 3) {
  117. u64 size[EMMC_PART_END];
  118. u32 i;
  119. if ((ext_csd[EXT_CSD_ERASE_GRP_DEF] & EXT_CSD_ERASE_GRP_DEF_EN)
  120. && (ext_csd[EXT_CSD_HC_WP_GPR_SIZE] > 0)) {
  121. wpg_sz = 512 * 1024 * ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
  122. ext_csd[EXT_CSD_HC_WP_GPR_SIZE];
  123. } else {
  124. wpg_sz = card->csd.write_prot_grpsz;
  125. }
  126. size[EMMC_PART_UNKNOWN] = 0;
  127. size[EMMC_PART_BOOT1] = ext_csd[EXT_CSD_BOOT_SIZE_MULT] * 128 * 1024;
  128. size[EMMC_PART_BOOT2] = ext_csd[EXT_CSD_BOOT_SIZE_MULT] * 128 * 1024;
  129. size[EMMC_PART_RPMB] = ext_csd[EXT_CSD_RPMB_SIZE_MULT] * 128 * 1024;
  130. size[EMMC_PART_GP1] = ext_csd[EXT_CSD_GP1_SIZE_MULT + 2] * 256 * 256 +
  131. ext_csd[EXT_CSD_GP1_SIZE_MULT + 1] * 256 +
  132. ext_csd[EXT_CSD_GP1_SIZE_MULT + 0];
  133. size[EMMC_PART_GP2] = ext_csd[EXT_CSD_GP2_SIZE_MULT + 2] * 256 * 256 +
  134. ext_csd[EXT_CSD_GP2_SIZE_MULT + 1] * 256 +
  135. ext_csd[EXT_CSD_GP2_SIZE_MULT + 0];
  136. size[EMMC_PART_GP3] = ext_csd[EXT_CSD_GP3_SIZE_MULT + 2] * 256 * 256 +
  137. ext_csd[EXT_CSD_GP3_SIZE_MULT + 1] * 256 +
  138. ext_csd[EXT_CSD_GP3_SIZE_MULT + 0];
  139. size[EMMC_PART_GP4] = ext_csd[EXT_CSD_GP4_SIZE_MULT + 2] * 256 * 256 +
  140. ext_csd[EXT_CSD_GP4_SIZE_MULT + 1] * 256 +
  141. ext_csd[EXT_CSD_GP4_SIZE_MULT + 0];
  142. size[EMMC_PART_USER] = (u64)card->blklen * card->nblks;
  143. size[EMMC_PART_GP1] *= wpg_sz;
  144. size[EMMC_PART_GP2] *= wpg_sz;
  145. size[EMMC_PART_GP3] *= wpg_sz;
  146. size[EMMC_PART_GP4] *= wpg_sz;
  147. for (i = EMMC_PART_BOOT1; i < EMMC_PART_END; i++) {
  148. g_emmc_addr_trans[i].id = i;
  149. g_emmc_addr_trans[i].len = size[i] / 512; /* in 512B unit */
  150. #if defined(MMC_MSDC_DRV_LK)
  151. if (i<EMMC_PART_USER)
  152. g_user_virt_addr += size[i];
  153. #endif
  154. g_emmc_size += size[i];
  155. }
  156. /* determine user area offset */
  157. #if defined(MMC_MSDC_DRV_PRELOADER)
  158. for (i = EMMC_PART_BOOT1; i < EMMC_PART_USER; i++) {
  159. bdev->offset += size[i];
  160. }
  161. bdev->offset /= bdev->blksz; /* in blksz unit */
  162. #endif
  163. g_emmc_user_size = size[EMMC_PART_USER];
  164. g_addr_trans_tbl.num = EMMC_PART_END;
  165. g_addr_trans_tbl.info = &g_emmc_addr_trans[0];
  166. } else {
  167. g_addr_trans_tbl.num = 0;
  168. g_addr_trans_tbl.info = NULL;
  169. }
  170. return 0;
  171. }
  172. int mmc_get_boot_part(int *bootpart)
  173. {
  174. struct mmc_card *card;
  175. struct mmc_host *host;
  176. int err = MMC_ERR_NONE;
  177. u8 *ext_csd;
  178. u8 part_config;
  179. if (!bootpart)
  180. return -1;
  181. card = mmc_get_card(MMC_HOST_ID);
  182. host = mmc_get_host(MMC_HOST_ID);
  183. if(!card || !host)
  184. return -1;
  185. err = mmc_read_ext_csd(host, card);
  186. if (err == MMC_ERR_NONE) {
  187. ext_csd = &card->raw_ext_csd[0];
  188. part_config = (ext_csd[EXT_CSD_PART_CFG] >> 3) & 0x07;
  189. if (part_config == 1) {
  190. *bootpart = EMMC_PART_BOOT1;
  191. }
  192. else if (part_config == 2) {
  193. *bootpart = EMMC_PART_BOOT2;
  194. }
  195. else if(part_config == 7) {
  196. *bootpart = EMMC_PART_USER;
  197. }
  198. else {
  199. MSG(ERR, "[PL MTK] fail to get boot part\n");
  200. return -1;
  201. }
  202. }
  203. return err;
  204. }
  205. int mmc_set_boot_part(u32 bootpart)
  206. {
  207. struct mmc_card *card;
  208. struct mmc_host *host;
  209. int err = MMC_ERR_NONE;
  210. u8 *ext_csd;
  211. u8 part_config;
  212. u8 cur_bootpart;
  213. if (bootpart != EMMC_PART_BOOT1
  214. && bootpart != EMMC_PART_BOOT2
  215. && bootpart != EMMC_PART_USER)
  216. return -1;
  217. card = mmc_get_card(MMC_HOST_ID);
  218. host = mmc_get_host(MMC_HOST_ID);
  219. if (!card || !host)
  220. return -1;
  221. err = mmc_read_ext_csd(host, card);
  222. if (err != MMC_ERR_NONE)
  223. goto out;
  224. part_config = card->raw_ext_csd[EXT_CSD_PART_CFG];
  225. cur_bootpart = (part_config >> 3) & 0x7;
  226. if (((u32)cur_bootpart) == bootpart)
  227. goto out;
  228. printf("[SD0] Current boot part is %d\n", cur_bootpart);
  229. part_config = part_config & (~(0x7 << 3)) | (bootpart << 3);
  230. printf("[SD0] Set boot part as %d\n", bootpart);
  231. err = mmc_switch(host, card,
  232. EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CFG, part_config);
  233. out:
  234. return err;
  235. }
  236. #if defined(MMC_MSDC_DRV_PRELOADER)
  237. static int mmc_bread(blkdev_t *bdev, u32 blknr, u32 blks, u8 *buf, u32 part_id)
  238. {
  239. struct mmc_host *host = (struct mmc_host*)bdev->priv;
  240. mmc_switch_part(part_id);
  241. return mmc_block_read(host->id, (unsigned long)blknr, blks, (unsigned long*)buf);
  242. }
  243. static int mmc_bwrite(blkdev_t *bdev, u32 blknr, u32 blks, u8 *buf, u32 part_id)
  244. {
  245. struct mmc_host *host = (struct mmc_host*)bdev->priv;
  246. mmc_switch_part(part_id);
  247. return mmc_block_write(host->id, (unsigned long)blknr, blks, (unsigned long*)buf);
  248. }
  249. // ==========================================================
  250. // MMC Common Interface - Init
  251. // ==========================================================
  252. u32 mmc_init_device(void)
  253. {
  254. int ret;
  255. struct mmc_card *card;
  256. if (!blkdev_get(BOOTDEV_SDMMC)) {
  257. ret = mmc_init(MMC_HOST_ID, MSDC_MODE_DEFAULT);
  258. if (ret != 0) {
  259. printf("[SD0] init card failed\n");
  260. return ret;
  261. }
  262. memset(&g_mmc_bdev, 0, sizeof(blkdev_t));
  263. card = mmc_get_card(MMC_HOST_ID);
  264. g_mmc_bdev.blksz = MMC_BLOCK_SIZE;
  265. g_mmc_bdev.erasesz = MMC_BLOCK_SIZE;
  266. g_mmc_bdev.blks = card->nblks;
  267. g_mmc_bdev.bread = mmc_bread;
  268. g_mmc_bdev.bwrite = mmc_bwrite;
  269. g_mmc_bdev.type = BOOTDEV_SDMMC;
  270. g_mmc_bdev.blkbuf = NULL;
  271. g_mmc_bdev.priv = (void*)mmc_get_host(MMC_HOST_ID);
  272. mmc_addr_trans_tbl_init(card, &g_mmc_bdev);
  273. blkdev_register(&g_mmc_bdev);
  274. }
  275. return 0;
  276. }
  277. u32 mmc_get_device_id(u8 *id, u32 len,u32 *fw_len)
  278. {
  279. u8 buf[16]; /* CID = 128 bits */
  280. struct mmc_card *card;
  281. u8 buf_sanid[512];
  282. u8 i;
  283. if (0 != mmc_init_device())
  284. return -1;
  285. card = mmc_get_card(MMC_HOST_ID);
  286. buf[0] = (card->raw_cid[0] >> 24) & 0xFF; /* Manufacturer ID */
  287. buf[1] = (card->raw_cid[0] >> 16) & 0xFF; /* Reserved(6)+Card/BGA(2) */
  288. buf[2] = (card->raw_cid[0] >> 8 ) & 0xFF; /* OEM/Application ID */
  289. buf[3] = (card->raw_cid[0] >> 0 ) & 0xFF; /* Product name [0] */
  290. buf[4] = (card->raw_cid[1] >> 24) & 0xFF; /* Product name [1] */
  291. buf[5] = (card->raw_cid[1] >> 16) & 0xFF; /* Product name [2] */
  292. buf[6] = (card->raw_cid[1] >> 8 ) & 0xFF; /* Product name [3] */
  293. buf[7] = (card->raw_cid[1] >> 0 ) & 0xFF; /* Product name [4] */
  294. buf[8] = (card->raw_cid[2] >> 24) & 0xFF; /* Product name [5] */
  295. buf[9] = (card->raw_cid[2] >> 16) & 0xFF; /* Product revision */
  296. buf[10] =(card->raw_cid[2] >> 8 ) & 0xFF; /* Serial Number [0] */
  297. buf[11] =(card->raw_cid[2] >> 0 ) & 0xFF; /* Serial Number [1] */
  298. buf[12] =(card->raw_cid[3] >> 24) & 0xFF; /* Serial Number [2] */
  299. buf[13] =(card->raw_cid[3] >> 16) & 0xFF; /* Serial Number [3] */
  300. buf[14] =(card->raw_cid[3] >> 8 ) & 0xFF; /* Manufacturer date */
  301. buf[15] =(card->raw_cid[3] >> 0 ) & 0xFF; /* CRC7 + stuff bit*/
  302. *fw_len = 1;
  303. /* sandisk */
  304. if(buf[0] == 0x45){
  305. /* before v4.41 */
  306. if (card->raw_ext_csd[EXT_CSD_REV] <= 5) {
  307. if (0 == mmc_get_sandisk_fwid(MMC_HOST_ID,buf_sanid)){
  308. *fw_len = 6;
  309. }
  310. } else if (card->raw_ext_csd[EXT_CSD_REV] == 6) { /* v4.5, v4.51 */
  311. /* do nothing, same as other vendor */
  312. } else if (card->raw_ext_csd[EXT_CSD_REV] == 7) { /* v5.0 */
  313. /* sandisk only use 6 bytes */
  314. *fw_len = 6;
  315. for (i=0; i<6; i++) {
  316. buf_sanid[32+i] = card->raw_ext_csd[EXT_CSD_FIRMWARE_VERSION+i];
  317. }
  318. }
  319. }
  320. len = len > 16 ? 16 : len;
  321. memcpy(id, buf, len);
  322. if(*fw_len == 6)
  323. memcpy(id+len,buf_sanid+32,6);
  324. else
  325. *(id+len) = buf[9];
  326. return 0;
  327. }
  328. int mmc_bread_boot(blkdev_t *bdev, u32 blknr, u32 blks, u8 *buf)
  329. {
  330. u32 pid, id;
  331. struct mmc_host *host;
  332. if(bdev && bdev->priv){
  333. host = (struct mmc_host*)bdev->priv;
  334. id = host->id;
  335. }else {
  336. MSG(ERR, "[%s]: invalid bdev, force the host id to 0\n", __func__, pid);
  337. id = 0;
  338. }
  339. if(mmc_get_boot_part(&pid)){
  340. MSG(ERR, "[%s]: invalid pid=%d\n", __func__, pid);
  341. return -1;
  342. }
  343. mmc_switch_part(pid);
  344. return mmc_block_read(id, (unsigned long)blknr, blks, (unsigned long*)buf);
  345. }
  346. int mmc_bwrite_boot(blkdev_t *bdev, u32 blknr, u32 blks, u8 *buf)
  347. {
  348. u32 pid, id;
  349. struct mmc_host *host;
  350. if(bdev && bdev->priv){
  351. host = (struct mmc_host*)bdev->priv;
  352. id = host->id;
  353. }else {
  354. id = 0;
  355. }
  356. if(mmc_get_boot_part(&pid)){
  357. MSG(ERR, "[%s]: invalid pid=%d\n", __func__, pid);
  358. return -1;
  359. }
  360. mmc_switch_part(pid);
  361. return mmc_block_write(id, (unsigned long)blknr, blks, (unsigned long*)buf);
  362. }
  363. #endif //#if defined(MMC_MSDC_DRV_PRELOADER)
  364. #if defined(MMC_MSDC_DRV_LK)
  365. #include <platform/partition.h>
  366. static block_dev_desc_t sd_dev[MSDC_MAX_NUM];
  367. static int boot_dev_found = 0;
  368. static part_dev_t boot_dev;
  369. unsigned long mmc_wrap_bread(int dev_num, unsigned long blknr, lbaint_t blkcnt, void *dst, unsigned int part_id)
  370. {
  371. mmc_switch_part(part_id);
  372. return mmc_block_read(dev_num, blknr, blkcnt, (unsigned long *)dst) == MMC_ERR_NONE ? blkcnt : (unsigned long) -1;
  373. }
  374. unsigned long mmc_wrap_bwrite(int dev_num, unsigned long blknr, lbaint_t blkcnt, const void *src, unsigned int part_id)
  375. {
  376. mmc_switch_part(part_id);
  377. return mmc_block_write(dev_num, blknr, blkcnt, (unsigned long *)src) == MMC_ERR_NONE ? blkcnt : (unsigned long) -1;
  378. }
  379. int mmc_legacy_init(int verbose)
  380. {
  381. int id = verbose - 1;
  382. int err = MMC_ERR_NONE;
  383. struct mmc_host *host;
  384. struct mmc_card *card;
  385. block_dev_desc_t *bdev;
  386. u8 *ext_csd;
  387. bdev = &sd_dev[id];
  388. //msdc_hard_reset(host);
  389. err = mmc_init(id, MSDC_MODE_DEFAULT);
  390. if (err == MMC_ERR_NONE && !boot_dev_found) {
  391. /* fill in device description */
  392. card=mmc_get_card(id);
  393. host=mmc_get_host(id);
  394. mmc_addr_trans_tbl_init(card);
  395. bdev->dev = id;
  396. bdev->type = BOOTDEV_SDMMC;
  397. bdev->blksz = MMC_BLOCK_SIZE;
  398. ext_csd = &card->raw_ext_csd[0];
  399. if (ext_csd[EXT_CSD_ERASE_GRP_DEF] & EXT_CSD_ERASE_GRP_DEF_EN)
  400. bdev->erasesz = card->ext_csd.hc_erase_grp_sz * 512 * 1024;
  401. else
  402. bdev->erasesz = card->csd.erase_sctsz * 512;
  403. bdev->lba = card->nblks * card->blklen / MMC_BLOCK_SIZE;
  404. bdev->blk_bits = 9;
  405. bdev->part_boot1 = EMMC_PART_BOOT1;
  406. bdev->part_boot2 = EMMC_PART_BOOT2;
  407. bdev->part_user = EMMC_PART_USER;
  408. bdev->block_read = mmc_wrap_bread;
  409. bdev->block_write = mmc_wrap_bwrite;
  410. #if defined(MEM_PRESERVED_MODE_ENABLE)
  411. if ( id==1 ) {
  412. host->boot_type = NON_BOOTABLE;
  413. return err;
  414. }
  415. #endif
  416. host->boot_type = RAW_BOOT;
  417. /* FIXME. only one RAW_BOOT dev */
  418. if (host->boot_type == RAW_BOOT) {
  419. boot_dev.id = id;
  420. boot_dev.init = 1;
  421. boot_dev.blkdev = bdev;
  422. boot_dev.erase = mmc_do_erase;
  423. mt_part_register_device(&boot_dev);
  424. boot_dev_found = 1;
  425. MSG(ERR, "[SD%d] boot device found\n", id);
  426. } else if (host->boot_type == FAT_BOOT) {
  427. #if (CONFIG_COMMANDS & CFG_CMD_FAT)
  428. if (0 == fat_register_device(bdev, 1)) {
  429. boot_dev_found = 1;
  430. MSG(ERR, "[SD%d] FAT partition found\n", id);
  431. }
  432. #endif
  433. }
  434. }
  435. return err;
  436. }
  437. // ==========================================================
  438. // MMC Common Interface - Erase
  439. // ==========================================================
  440. static int __mmc_do_erase(struct mmc_host *host,struct mmc_card *card, u64 start_addr, u64 len)
  441. {
  442. int err = MMC_ERR_NONE;
  443. u64 end_addr =((start_addr + len + card->blklen - 1)/card->blklen - 1) * card->blklen;
  444. u8 buf[512];
  445. if (end_addr/card->blklen > (card->nblks - 1)) {
  446. MSG(ERR, "[MSDC%d]Erase address out of range! start<0x%llx>,len<0x%llx>,card_nblks<0x%x>\n",host->id, start_addr, len, card->nblks);
  447. return MMC_ERR_INVALID;
  448. }
  449. resend:
  450. /* Add dummy read to reset erase sequence error. */
  451. err = mmc_block_read(host->id, 0, 1, (unsigned long*)buf);
  452. if (err != MMC_ERR_NONE) {
  453. MSG(ERR, "[MSDC%d]Fail in read card\n", host->id);
  454. goto out;
  455. }
  456. err = mmc_erase_start(card, start_addr);
  457. if (err != MMC_ERR_NONE) {
  458. MSG(ERR, "[MSDC%d]Set erase start addrees 0x%llx failed,Err<%d>\n", host->id, start_addr, err);
  459. if (err == MMC_ERR_ERASE_SEQ) {
  460. MSG(ERR, "[MSDC%d]Erase sequence error, retry erase.\n", host->id);
  461. goto resend;
  462. } else {
  463. goto out;
  464. }
  465. }
  466. err = mmc_erase_end(card, end_addr);
  467. if (err != MMC_ERR_NONE) {
  468. MSG(ERR, "[MSDC%d]Set erase end addrees 0x%llx + 0x%llx failed,Err<%d>\n", host->id, start_addr, len, err);
  469. if (err == MMC_ERR_ERASE_SEQ) {
  470. MSG(ERR, "[MSDC%d]Erase sequence error, retry erase.\n", host->id);
  471. goto resend;
  472. } else {
  473. goto out;
  474. }
  475. }
  476. err = mmc_erase(card, MMC_ERASE_TRIM);
  477. if (err != MMC_ERR_NONE) {
  478. MSG(ERR "[MSDC%d]Set erase <0x%llx - 0x%llx> failed,Err<%d>\n", host->id, start_addr, start_addr + len, err);
  479. goto out;
  480. }
  481. printf("[MSDC%d]0x%llx - 0x%llx Erased\n", host->id, start_addr, start_addr + len);
  482. out:
  483. return err;
  484. }
  485. int mmc_do_erase(int dev_num,u64 start_addr,u64 len,u32 part_id)
  486. {
  487. struct mmc_host *host = mmc_get_host(dev_num);
  488. struct mmc_card *card = mmc_get_card(dev_num);
  489. u32 err;
  490. if ((!card) || (!host) ) {
  491. MSG(ERR, "[mmc_do_erase] card or host is NULL\n");
  492. return MMC_ERR_INVALID;
  493. }
  494. if (!len ){
  495. MSG(ERR, "[MSDC%d] invalid erase size! len<0x%llx>\n",host->id,len);
  496. return MMC_ERR_INVALID;
  497. }
  498. if ((start_addr % card->blklen) || (len % card->blklen)) {
  499. MSG(ERR, "[MSDC%d] non-alignment erase address! start<0x%llx>,len<0x%llx>,card_nblks<0x%x>\n",host->id,start_addr,len,card->nblks);
  500. return MMC_ERR_INVALID;
  501. }
  502. if ((err = mmc_switch_part(part_id))) {
  503. MSG(ERR, "[MSDC%d] mmc swtich failed.part<%d> error <%d> \n", host->id, part_id, err);
  504. return err;
  505. }
  506. if ((err = __mmc_do_erase(host, card, start_addr, len))) {
  507. MSG(ERR "[MSDC%d] mmc erase failed.error <%d> \n",host->id, err);
  508. return err;
  509. }
  510. return err;
  511. }
  512. #endif // #if defined(MMC_MSDC_DRV_LK)
  513. #endif //!defined(MMC_MSDC_DRV_CTP)