mmc_common_inter.c 19 KB

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