mmc_common_inter.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  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. #include "msdc.h"
  33. #if defined(MMC_MSDC_DRV_LK)
  34. #include "block_generic_interface.h"
  35. #include "mt_gpt.h"
  36. #endif
  37. #if !defined(MMC_MSDC_DRV_CTP)
  38. #define MMC_HOST_ID 0
  39. #define BUF_BLK_NUM 4 /* 4 * 512bytes = 2KB */
  40. /**************************************************************************
  41. * DEBUG CONTROL
  42. **************************************************************************/
  43. /**************************************************************************
  44. * MACRO DEFINITION
  45. **************************************************************************/
  46. /**************************************************************************
  47. * EXTERNAL DECLARATION
  48. **************************************************************************/
  49. static int mmc_do_erase(int dev_num, u64 start_addr, u64 len, u32 part_id);
  50. #if defined(MMC_MSDC_DRV_PRELOADER)
  51. extern struct nand_chip g_nand_chip;
  52. static blkdev_t g_mmc_bdev;
  53. #endif
  54. #if defined(MMC_MSDC_DRV_LK)
  55. u64 g_emmc_size = 0;
  56. #endif
  57. u64 g_emmc_user_size = 0;
  58. int mmc_switch_part(u32 part_id)
  59. {
  60. int err = MMC_ERR_NONE;
  61. struct mmc_card *card;
  62. #ifdef MTK_EMMC_SUPPORT
  63. struct mmc_host *host;
  64. u8 cfg;
  65. #endif
  66. u8 part = (u8)part_id;
  67. u8 *ext_csd;
  68. card = mmc_get_card(MMC_HOST_ID);
  69. #ifdef MTK_EMMC_SUPPORT
  70. host = mmc_get_host(MMC_HOST_ID);
  71. #endif
  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. static u64 mmc_get_emmc_size(struct mmc_card *card)
  104. {
  105. u64 size_tmp = 0ULL;
  106. size_tmp += card->ext_csd.boot_part_sz * 2;
  107. size_tmp += card->ext_csd.rpmb_sz;
  108. size_tmp += 512ULL * card->wp_size *
  109. (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]);
  110. size_tmp += (u64)card->blklen * card->nblks;
  111. return size_tmp;
  112. }
  113. #if defined(FEATURE_MMC_BOOT_ACCESS)
  114. int mmc_get_boot_part(u32 *bootpart)
  115. {
  116. struct mmc_card *card;
  117. struct mmc_host *host;
  118. int err = MMC_ERR_NONE;
  119. u8 *ext_csd;
  120. u8 part_config;
  121. if (!bootpart)
  122. return -1;
  123. card = mmc_get_card(MMC_HOST_ID);
  124. host = mmc_get_host(MMC_HOST_ID);
  125. if (!card || !host)
  126. return -1;
  127. err = mmc_read_ext_csd(host, card);
  128. if (err == MMC_ERR_NONE) {
  129. ext_csd = &card->raw_ext_csd[0];
  130. part_config = (ext_csd[EXT_CSD_PART_CFG] >> 3) & 0x07;
  131. if (part_config == 1) {
  132. *bootpart = EMMC_PART_BOOT1;
  133. } else if (part_config == 2) {
  134. *bootpart = EMMC_PART_BOOT2;
  135. } else if (part_config == 7) {
  136. *bootpart = EMMC_PART_USER;
  137. } else {
  138. msdc_pr_err("[PL MTK] fail to get boot part\n");
  139. return -1;
  140. }
  141. }
  142. return err;
  143. }
  144. #endif
  145. #if defined(MMC_MSDC_DRV_PRELOADER)
  146. static int mmc_bread(blkdev_t *bdev, u32 blknr, u32 blks, u8 *buf, u32 part_id)
  147. {
  148. struct mmc_host *host = (struct mmc_host*)bdev->priv;
  149. mmc_switch_part(part_id);
  150. return mmc_block_read(host->id, (unsigned long)blknr, blks, (unsigned long*)buf);
  151. }
  152. static int mmc_bwrite(blkdev_t *bdev, u32 blknr, u32 blks, u8 *buf, u32 part_id)
  153. {
  154. struct mmc_host *host = (struct mmc_host*)bdev->priv;
  155. mmc_switch_part(part_id);
  156. return mmc_block_write(host->id, (unsigned long)blknr, blks, (unsigned long*)buf);
  157. }
  158. // ==========================================================
  159. // MMC Common Interface - Init
  160. // ==========================================================
  161. u32 mmc_init_device(void)
  162. {
  163. int ret;
  164. struct mmc_card *card;
  165. if (!blkdev_get(BOOTDEV_SDMMC)) {
  166. ret = mmc_init(MMC_HOST_ID, MSDC_MODE_DEFAULT);
  167. if (ret != 0) {
  168. msdc_pr_err("[SD0] init card failed\n");
  169. return ret;
  170. }
  171. #if defined(SLT)
  172. msdc_apply_timing(MMC_HOST_ID);
  173. #endif
  174. memset(&g_mmc_bdev, 0, sizeof(blkdev_t));
  175. card = mmc_get_card(MMC_HOST_ID);
  176. g_mmc_bdev.blksz = MMC_BLOCK_SIZE;
  177. g_mmc_bdev.erasesz = MMC_BLOCK_SIZE;
  178. g_mmc_bdev.blks = card->nblks;
  179. g_mmc_bdev.bread = mmc_bread;
  180. g_mmc_bdev.bwrite = mmc_bwrite;
  181. g_mmc_bdev.type = BOOTDEV_SDMMC;
  182. g_mmc_bdev.blkbuf = NULL;
  183. g_mmc_bdev.priv = (void*)mmc_get_host(MMC_HOST_ID);
  184. g_mmc_bdev.offset = mmc_get_emmc_size(card) / MMC_BLOCK_SIZE; /* in blksz unit */
  185. g_emmc_user_size = (u64)card->blklen * card->nblks;
  186. blkdev_register(&g_mmc_bdev);
  187. }
  188. return 0;
  189. }
  190. #if defined(FEATURE_EMCP)
  191. u32 mmc_get_device_id(u8 *id, u32 len,u32 *fw_len)
  192. {
  193. u8 buf[16]; /* CID = 128 bits */
  194. struct mmc_card *card;
  195. u8 buf_sanid[512];
  196. u8 i;
  197. if (0 != mmc_init_device())
  198. return -1;
  199. card = mmc_get_card(MMC_HOST_ID);
  200. buf[0] = (card->raw_cid[0] >> 24) & 0xFF; /* Manufacturer ID */
  201. buf[1] = (card->raw_cid[0] >> 16) & 0xFF; /* Reserved(6)+Card/BGA(2) */
  202. buf[2] = (card->raw_cid[0] >> 8 ) & 0xFF; /* OEM/Application ID */
  203. buf[3] = (card->raw_cid[0] >> 0 ) & 0xFF; /* Product name [0] */
  204. buf[4] = (card->raw_cid[1] >> 24) & 0xFF; /* Product name [1] */
  205. buf[5] = (card->raw_cid[1] >> 16) & 0xFF; /* Product name [2] */
  206. buf[6] = (card->raw_cid[1] >> 8 ) & 0xFF; /* Product name [3] */
  207. buf[7] = (card->raw_cid[1] >> 0 ) & 0xFF; /* Product name [4] */
  208. buf[8] = (card->raw_cid[2] >> 24) & 0xFF; /* Product name [5] */
  209. buf[9] = (card->raw_cid[2] >> 16) & 0xFF; /* Product revision */
  210. buf[10] =(card->raw_cid[2] >> 8 ) & 0xFF; /* Serial Number [0] */
  211. buf[11] =(card->raw_cid[2] >> 0 ) & 0xFF; /* Serial Number [1] */
  212. buf[12] =(card->raw_cid[3] >> 24) & 0xFF; /* Serial Number [2] */
  213. buf[13] =(card->raw_cid[3] >> 16) & 0xFF; /* Serial Number [3] */
  214. buf[14] =(card->raw_cid[3] >> 8 ) & 0xFF; /* Manufacturer date */
  215. buf[15] =(card->raw_cid[3] >> 0 ) & 0xFF; /* CRC7 + stuff bit*/
  216. *fw_len = 1;
  217. /* sandisk */
  218. if (buf[0] == 0x45) {
  219. /* before v4.41 */
  220. if (card->raw_ext_csd[EXT_CSD_REV] <= 5) {
  221. if (0 == mmc_get_sandisk_fwid(MMC_HOST_ID,buf_sanid)) {
  222. *fw_len = 6;
  223. }
  224. } else if (card->raw_ext_csd[EXT_CSD_REV] == 6) { /* v4.5, v4.51 */
  225. /* do nothing, same as other vendor */
  226. } else if (card->raw_ext_csd[EXT_CSD_REV] == 7) { /* v5.0 */
  227. /* sandisk only use 6 bytes */
  228. *fw_len = 6;
  229. for (i=0; i<6; i++) {
  230. buf_sanid[32+i] = card->raw_ext_csd[EXT_CSD_FIRMWARE_VERSION+i];
  231. }
  232. }
  233. }
  234. len = len > 16 ? 16 : len;
  235. memcpy(id, buf, len);
  236. if (*fw_len == 6)
  237. memcpy(id+len,buf_sanid+32,6);
  238. else
  239. *(id+len) = buf[9];
  240. return 0;
  241. }
  242. #endif
  243. #if defined(FEATURE_MMC_BOOT_ACCESS)
  244. int mmc_bread_boot(blkdev_t *bdev, u32 blknr, u32 blks, u8 *buf)
  245. {
  246. u32 pid, id;
  247. struct mmc_host *host;
  248. if (bdev && bdev->priv) {
  249. host = (struct mmc_host*)bdev->priv;
  250. id = host->id;
  251. } else {
  252. msdc_pr_err("[%s]: invalid bdev, force the host id to 0\n", __func__);
  253. id = 0;
  254. }
  255. if (mmc_get_boot_part(&pid)) {
  256. msdc_pr_err("[%s]: invalid pid=%d\n", __func__, pid);
  257. return -1;
  258. }
  259. mmc_switch_part(pid);
  260. return mmc_block_read(id, (unsigned long)blknr, blks, (unsigned long*)buf);
  261. }
  262. int mmc_bwrite_boot(blkdev_t *bdev, u32 blknr, u32 blks, u8 *buf)
  263. {
  264. u32 pid, id;
  265. struct mmc_host *host;
  266. if (bdev && bdev->priv) {
  267. host = (struct mmc_host*)bdev->priv;
  268. id = host->id;
  269. } else {
  270. id = 0;
  271. }
  272. if (mmc_get_boot_part(&pid)) {
  273. msdc_pr_err("[%s]: invalid pid=%d\n", __func__, pid);
  274. return -1;
  275. }
  276. mmc_switch_part(pid);
  277. return mmc_block_write(id, (unsigned long)blknr, blks, (unsigned long*)buf);
  278. }
  279. #endif
  280. #endif //#if defined(MMC_MSDC_DRV_PRELOADER)
  281. #if defined(MMC_MSDC_DRV_LK)
  282. #include "part_dev.h"
  283. static block_dev_desc_t sd_dev[MSDC_MAX_NUM];
  284. static int boot_dev_found = 0;
  285. static part_dev_t boot_dev;
  286. unsigned long mmc_wrap_bread(int dev_num, unsigned long blknr, lbaint_t blkcnt, void *dst, unsigned int part_id)
  287. {
  288. unsigned long ret;
  289. #ifdef LK_PROFILING
  290. unsigned long t1, t2;
  291. t1 = get_timer(0);
  292. #endif
  293. mmc_switch_part(part_id);
  294. if (mmc_block_read(dev_num, blknr, blkcnt, (unsigned long *)dst) == MMC_ERR_NONE)
  295. ret = blkcnt;
  296. else
  297. ret = (unsigned long) -1;
  298. #ifdef LK_PROFILING
  299. t2 = get_timer(t1);
  300. msdc_pr_err("[PROFILE] mmc read %d blks in %d ms: %dKB/s\n", blkcnt, t2, blkcnt * 500 / t2);
  301. #endif
  302. return ret;
  303. }
  304. unsigned long mmc_wrap_bwrite(int dev_num, unsigned long blknr, lbaint_t blkcnt, const void *src, unsigned int part_id)
  305. {
  306. unsigned long ret;
  307. #ifdef LK_PROFILING
  308. unsigned long t1, t2;
  309. t1 = get_timer(0);
  310. #endif
  311. mmc_switch_part(part_id);
  312. if (mmc_block_write(dev_num, blknr, blkcnt, (unsigned long *)src) == MMC_ERR_NONE)
  313. ret = blkcnt;
  314. else
  315. ret = (unsigned long) -1;
  316. #ifdef LK_PROFILING
  317. t2 = get_timer(t1);
  318. msdc_pr_err("[PROFILE] mmc write %d blks in %d ms: %dKB/s\n", blkcnt, t2, blkcnt * 500 / t2);
  319. #endif
  320. return ret;
  321. }
  322. int mmc_legacy_init(int verbose)
  323. {
  324. int id = verbose - 1;
  325. int err = MMC_ERR_NONE;
  326. struct mmc_host *host;
  327. struct mmc_card *card;
  328. block_dev_desc_t *bdev;
  329. u8 *ext_csd;
  330. bdev = &sd_dev[id];
  331. //msdc_hard_reset(host);
  332. err = mmc_init(id, MSDC_MODE_DEFAULT);
  333. if (err == MMC_ERR_NONE && !boot_dev_found) {
  334. /* fill in device description */
  335. card=mmc_get_card(id);
  336. host=mmc_get_host(id);
  337. g_emmc_size = mmc_get_emmc_size(card);
  338. g_emmc_user_size = (u64)card->blklen * card->nblks;
  339. bdev->dev = id;
  340. bdev->type = BOOTDEV_SDMMC;
  341. bdev->blksz = MMC_BLOCK_SIZE;
  342. ext_csd = &card->raw_ext_csd[0];
  343. if (ext_csd[EXT_CSD_ERASE_GRP_DEF] & EXT_CSD_ERASE_GRP_DEF_EN)
  344. bdev->erasesz = card->ext_csd.hc_erase_grp_sz * 512 * 1024;
  345. else
  346. bdev->erasesz = card->csd.erase_sctsz * 512;
  347. bdev->lba = card->nblks * card->blklen / MMC_BLOCK_SIZE;
  348. bdev->blk_bits = 9;
  349. bdev->part_boot1 = EMMC_PART_BOOT1;
  350. bdev->part_boot2 = EMMC_PART_BOOT2;
  351. bdev->part_user = EMMC_PART_USER;
  352. bdev->block_read = mmc_wrap_bread;
  353. bdev->block_write = mmc_wrap_bwrite;
  354. #if defined(MEM_PRESERVED_MODE_ENABLE)
  355. if (id==1) {
  356. host->boot_type = NON_BOOTABLE;
  357. return err;
  358. }
  359. #endif
  360. host->boot_type = RAW_BOOT;
  361. /* FIXME. only one RAW_BOOT dev */
  362. if (host->boot_type == RAW_BOOT) {
  363. boot_dev.id = id;
  364. boot_dev.init = 1;
  365. boot_dev.blkdev = bdev;
  366. boot_dev.erase = mmc_do_erase;
  367. mt_part_register_device(&boot_dev);
  368. boot_dev_found = 1;
  369. msdc_pr_info("[SD%d] boot device found\n", id);
  370. } else if (host->boot_type == FAT_BOOT) {
  371. #if (CONFIG_COMMANDS & CFG_CMD_FAT)
  372. if (0 == fat_register_device(bdev, 1)) {
  373. boot_dev_found = 1;
  374. msdc_pr_info("[SD%d] FAT partition found\n", id);
  375. }
  376. #endif
  377. }
  378. }
  379. return err;
  380. }
  381. // ==========================================================
  382. // MMC Common Interface - Erase
  383. // ==========================================================
  384. static int __mmc_do_erase(struct mmc_host *host,struct mmc_card *card, u64 start_addr, u64 len)
  385. {
  386. int err = MMC_ERR_NONE;
  387. u64 end_addr =((start_addr + len + card->blklen - 1)/card->blklen - 1) * card->blklen;
  388. u8 buf[512];
  389. if (end_addr/card->blklen > card->nblks - 1) {
  390. msdc_pr_err("[MSDC%d]Erase address out of range! start<0x%llx>,len<0x%llx>,card_nblks<0x%x>\n",
  391. host->id, start_addr, len, card->nblks);
  392. return MMC_ERR_INVALID;
  393. }
  394. resend:
  395. err = mmc_erase_start(card, start_addr);
  396. if (err != MMC_ERR_NONE) {
  397. msdc_pr_err("[MSDC%d]Set erase start addrees 0x%llx failed,Err<%d>\n", host->id, start_addr, err);
  398. if (err == MMC_ERR_ERASE_SEQ) {
  399. msdc_pr_err("[MSDC%d]Erase sequence error, retry erase.\n", host->id);
  400. goto dummy_read;
  401. } else {
  402. goto out;
  403. }
  404. }
  405. err = mmc_erase_end(card, end_addr);
  406. if (err != MMC_ERR_NONE) {
  407. msdc_pr_err("[MSDC%d]Set erase end addrees 0x%llx + 0x%llx failed,Err<%d>\n", host->id, start_addr, len, err);
  408. if (err == MMC_ERR_ERASE_SEQ) {
  409. msdc_pr_err("[MSDC%d]Erase sequence error, retry erase.\n", host->id);
  410. goto dummy_read;
  411. } else {
  412. goto out;
  413. }
  414. }
  415. err = mmc_erase(card, MMC_ERASE_TRIM);
  416. if (err != MMC_ERR_NONE) {
  417. msdc_pr_err("[MSDC%d]Set erase <0x%llx - 0x%llx> failed,Err<%d>\n", host->id, start_addr, start_addr + len, err);
  418. goto out;
  419. }
  420. msdc_pr_info("[MSDC%d]0x%llx - 0x%llx Erased\n", host->id, start_addr, start_addr + len);
  421. out:
  422. return err;
  423. dummy_read:
  424. /* Add dummy read to reset erase sequence error. */
  425. err = mmc_block_read(host->id, 0, 1, (unsigned long*)buf);
  426. if (err != MMC_ERR_NONE) {
  427. msdc_pr_err("[MSDC%d]Fail in read card\n", host->id);
  428. goto out;
  429. }
  430. goto resend;
  431. }
  432. int mmc_do_erase(int dev_num, u64 start_addr, u64 len, u32 part_id)
  433. {
  434. struct mmc_host *host = mmc_get_host(dev_num);
  435. struct mmc_card *card = mmc_get_card(dev_num);
  436. //struct mmc_erase_part erase_part[EMMC_PART_END];
  437. u32 err;
  438. if (!card || !host) {
  439. msdc_pr_err("[mmc_do_erase] card or host is NULL\n");
  440. return MMC_ERR_INVALID;
  441. }
  442. if (!len) {
  443. msdc_pr_err("[MSDC%d] invalid erase size! len<0x%llx>\n",host->id,len);
  444. return MMC_ERR_INVALID;
  445. }
  446. if ((start_addr % card->blklen) || (len % card->blklen)) {
  447. msdc_pr_err("[MSDC%d] non-alignment erase address! start<0x%llx>,len<0x%llx>,card_nblks<0x%x>\n",
  448. host->id, start_addr, len, card->nblks);
  449. return MMC_ERR_INVALID;
  450. }
  451. if ((err = mmc_switch_part(part_id))) {
  452. msdc_pr_err("[MSDC%d] mmc swtich failed.part<%d> error <%d> \n", host->id, part_id, err);
  453. return err;
  454. }
  455. if ((err = __mmc_do_erase(host, card, start_addr, len))) {
  456. msdc_pr_err("[MSDC%d] mmc erase failed.error <%d> \n",host->id, err);
  457. return err;
  458. }
  459. return err;
  460. }
  461. #endif // #if defined(MMC_MSDC_DRV_LK)
  462. #endif //!defined(MMC_MSDC_DRV_CTP)
  463. #if defined(SLT) || defined(MMC_MSDC_DRV_CTP)
  464. /* copy from autok.c */
  465. #define AUTOK_CKGEN_VALUE (0)
  466. #define AUTOK_CMD_LATCH_EN_HS400_PORT0_VALUE (3)
  467. #define AUTOK_CRC_LATCH_EN_HS400_PORT0_VALUE (3)
  468. #define AUTOK_CMD_LATCH_EN_DDR208_PORT3_VALUE (3)
  469. #define AUTOK_CRC_LATCH_EN_DDR208_PORT3_VALUE (3)
  470. #define AUTOK_CMD_LATCH_EN_HS200_PORT0_VALUE (2)
  471. #define AUTOK_CRC_LATCH_EN_HS200_PORT0_VALUE (2)
  472. #define AUTOK_CMD_LATCH_EN_SDR104_PORT1_VALUE (2)
  473. #define AUTOK_CRC_LATCH_EN_SDR104_PORT1_VALUE (2)
  474. #define AUTOK_CMD_LATCH_EN_HS_VALUE (1)
  475. #define AUTOK_CRC_LATCH_EN_HS_VALUE (1)
  476. void msdc_apply_timing(unsigned int id)
  477. {
  478. struct mmc_host *host;
  479. msdc_priv_t *priv;
  480. int mode;
  481. u32 base;
  482. u32 hz, div;
  483. host = mmc_get_host(id);
  484. priv = host->priv;
  485. base = host->base;
  486. hz = host->cur_bus_clk;
  487. MSDC_SET_FIELD(host->base + 0x208, (0x1 << 9), 0);
  488. if (priv->tuning_mode == MSDC_PATH_USE_DELAY_LINE) {
  489. msdc_pr_err("[SD%d] \"delay cell + clock tune\" is not supported\n", id);
  490. } else if (priv->tuning_mode == MSDC_PATH_USE_ASYNC_FIFO) {
  491. MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKMOD, mode);
  492. MSDC_GET_FIELD(MSDC_CFG, MSDC_CFG_CKDIV, div);
  493. if ((id == 0) && (mode == 3) && (host->src_clk==312000000)) {
  494. MSDC_SET_FIELD(host->base + 0x4, (0x1 << 1), 0x0); /*MSDC_IOCON[MSDC_IOCON_RSPL] */
  495. MSDC_SET_FIELD(host->base + 0x4, (0x1 << 2), 0); /* MSDC_IOCON[MSDC_IOCON_R_D_SMPL] */
  496. MSDC_SET_FIELD(host->base + 0xb4, (0xf << 8), 3); /* MSDC_PB1_STOP_DLY_SEL */
  497. MSDC_SET_FIELD(host->base + 0xb8, (0x7 << 29), AUTOK_CRC_LATCH_EN_HS400_PORT0_VALUE);
  498. MSDC_SET_FIELD(host->base + 0xb8, (0x7 << 16), AUTOK_CMD_LATCH_EN_HS400_PORT0_VALUE);
  499. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x0, (0x1 << 13), 0x1); /* EMMC_TOP_CONTROL[PAD_DAT_RD_RXDLY_SEL] */
  500. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x0, (0x1f << 7), 0x1); /* EMMC_TOP_CONTROL[PAD_DAT_RD_RXDLY] */
  501. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x0, (0x1 << 12), 0x0); /* EMMC_TOP_CONTROL[PAD_DAT_RD_RXDLY2_SEL] */
  502. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x0, (0x1f << 2), 0x0); /* EMMC_TOP_CONTROL[PAD_DAT_RD_RXDLY2] */
  503. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1 << 11), 0x0); /* EMMC_TOP_CMD[PAD_CMD_RXDLY] */
  504. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1f << 5), 0x0); /* EMMC_TOP_CMD[PAD_CMD_RXDLY_SEL] */
  505. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1 << 10), 0x0); /* EMMC_TOP_CMD[PAD_CMD_RXDLY2] */
  506. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1f << 0), 0x0); /* EMMC_TOP_CMD[PAD_CMD_RXDLY2_SEL] */
  507. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1f << 12), 0x0); /* EMMC_TOP_CMD_LEVEL1[PAD_CMD_TX_DLY] */
  508. MSDC_WRITE32(MSDC_TOP_BASE + 0x8, 0x3); /* EMMC50_PAD_CTL0 */
  509. MSDC_SET_FIELD(MSDC_TOP_BASE + 0xC, (0x1 << 16), 0x1); /* EMMC50_PAD_DS_TUNE[PAD_DS_DLY_SEL] */
  510. MSDC_SET_FIELD(MSDC_TOP_BASE + 0xC, (0x1f << 10), 0xb); /* EMMC50_PAD_DS_TUNE[PAD_DS_DLY1] */
  511. MSDC_SET_FIELD(MSDC_TOP_BASE + 0xC, (0x1 << 15), 0x0); /* EMMC50_PAD_DS_TUNE[PAD_DS_DLY2_SEL] */
  512. MSDC_SET_FIELD(MSDC_TOP_BASE + 0xC, (0x1 << 5), 0x0); /* EMMC50_PAD_DS_TUNE[PAD_DS_DLY2] */
  513. MSDC_SET_FIELD(MSDC_TOP_BASE + 0xC, (0x1f << 0), 0x1f); /* EMMC50_PAD_DS_TUNE[PAD_DS_DLY3] */
  514. MSDC_SET_FIELD(host->base + 0x208, (0x1 << 3), 0); /* MSDC_PB2_CFGCRCSTSEDGE, write crc stage edge */
  515. } else if ((id == 0) && (mode == 3) && (host->src_clk==364000000)) {
  516. MSDC_SET_FIELD(host->base + 0x4, (0x1 << 1), 0x0); /*MSDC_IOCON[MSDC_IOCON_RSPL] */
  517. MSDC_SET_FIELD(host->base + 0x4, (0x1 << 2), 0); /* MSDC_IOCON[MSDC_IOCON_R_D_SMPL] */
  518. MSDC_SET_FIELD(host->base + 0xb4, (0xf << 8), 3); /* MSDC_PB1_STOP_DLY_SEL */
  519. MSDC_SET_FIELD(host->base + 0xb8, (0x7 << 29), AUTOK_CRC_LATCH_EN_HS400_PORT0_VALUE);
  520. MSDC_SET_FIELD(host->base + 0xb8, (0x7 << 16), AUTOK_CMD_LATCH_EN_HS400_PORT0_VALUE);
  521. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x0, (0x1 << 13), 0x1); /* EMMC_TOP_CONTROL[PAD_DAT_RD_RXDLY_SEL] */
  522. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x0, (0x1f << 7), 0x1); /* EMMC_TOP_CONTROL[PAD_DAT_RD_RXDLY] */
  523. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x0, (0x1 << 12), 0x0); /* EMMC_TOP_CONTROL[PAD_DAT_RD_RXDLY2_SEL] */
  524. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x0, (0x1f << 2), 0x0); /* EMMC_TOP_CONTROL[PAD_DAT_RD_RXDLY2] */
  525. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1 << 11), 0x0); /* EMMC_TOP_CMD[PAD_CMD_RXDLY] */
  526. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1f << 5), 0x0); /* EMMC_TOP_CMD[PAD_CMD_RXDLY_SEL] */
  527. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1 << 10), 0x0); /* EMMC_TOP_CMD[PAD_CMD_RXDLY2] */
  528. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1f << 0), 0x0); /* EMMC_TOP_CMD[PAD_CMD_RXDLY2_SEL] */
  529. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1f << 12), 0x0); /* EMMC_TOP_CMD_LEVEL1[PAD_CMD_TX_DLY] */
  530. MSDC_WRITE32(MSDC_TOP_BASE + 0x8, 0x3); /* EMMC50_PAD_CTL0 */
  531. MSDC_SET_FIELD(MSDC_TOP_BASE + 0xC, (0x1 << 16), 0x1); /* EMMC50_PAD_DS_TUNE[PAD_DS_DLY_SEL] */
  532. MSDC_SET_FIELD(MSDC_TOP_BASE + 0xC, (0x1f << 10), 0xd); /* EMMC50_PAD_DS_TUNE[PAD_DS_DLY1] */
  533. MSDC_SET_FIELD(MSDC_TOP_BASE + 0xC, (0x1 << 15), 0x0); /* EMMC50_PAD_DS_TUNE[PAD_DS_DLY2_SEL] */
  534. MSDC_SET_FIELD(MSDC_TOP_BASE + 0xC, (0x1 << 5), 0x0); /* EMMC50_PAD_DS_TUNE[PAD_DS_DLY2] */
  535. MSDC_SET_FIELD(MSDC_TOP_BASE + 0xC, (0x1f << 0), 0x1f); /* EMMC50_PAD_DS_TUNE[PAD_DS_DLY3] */
  536. MSDC_SET_FIELD(host->base + 0x208, (0x1 << 3), 0); /* MSDC_PB2_CFGCRCSTSEDGE, write crc stage edge */
  537. } else if ((id == 0) && (div == 0) && (host->src_clk==364000000)) {
  538. MSDC_SET_FIELD(host->base + 0x4, (0x1 << 1), 0x0); /*MSDC_IOCON[MSDC_IOCON_RSPL] */
  539. MSDC_SET_FIELD(host->base + 0x4, (0x1 << 2), 0x0); /* MSDC_IOCON[MSDC_IOCON_R_D_SMPL] */
  540. MSDC_SET_FIELD(host->base + 0xb0, (0x7 << 7), 0x2); /* PATCH_BIT0[MSDC_PB0_INT_DAT_LATCH_CK_SEL] */
  541. MSDC_SET_FIELD(host->base + 0xb0, (0x1 << 3), 0x0);
  542. MSDC_SET_FIELD(host->base + 0xb4, (0xf << 8), 3); /* MSDC_PB1_STOP_DLY_SEL */
  543. MSDC_SET_FIELD(host->base + 0xb8, (0x7 << 29), AUTOK_CRC_LATCH_EN_HS200_PORT0_VALUE);
  544. MSDC_SET_FIELD(host->base + 0xb8, (0x7 << 16), AUTOK_CMD_LATCH_EN_HS200_PORT0_VALUE);
  545. MSDC_SET_FIELD(host->base + 0xb8, (0x1 << 25), 0); /* MSDC_PB2_CFGCRCSTSEDGE, write crc stage edge */
  546. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x0, (0x1 << 13), 0x1); /* EMMC_TOP_CONTROL[PAD_DAT_RD_RXDLY_SEL] */
  547. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x0, (0x1f << 7), 0x8); /* EMMC_TOP_CONTROL[PAD_DAT_RD_RXDLY] */
  548. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x0, (0x1 << 12), 0x0); /* EMMC_TOP_CONTROL[PAD_DAT_RD_RXDLY2_SEL] */
  549. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x0, (0x1f << 2), 0x0); /* EMMC_TOP_CONTROL[PAD_DAT_RD_RXDLY2] */
  550. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1 << 11), 0x0); /* EMMC_TOP_CMD[PAD_CMD_RXDLY] */
  551. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1f << 5), 0x0); /* EMMC_TOP_CMD[PAD_CMD_RXDLY_SEL] */
  552. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1 << 10), 0x0); /* EMMC_TOP_CMD[PAD_CMD_RXDLY2] */
  553. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1f << 0), 0x0); /* EMMC_TOP_CMD[PAD_CMD_RXDLY2_SEL] */
  554. MSDC_SET_FIELD(MSDC_TOP_BASE + 0x4, (0x1f << 12), 0x0); /* EMMC_TOP_CMD_LEVEL1[PAD_CMD_TX_DLY] */
  555. MSDC_WRITE32(MSDC_TOP_BASE + 0x8, 0x3); /* EMMC50_PAD_CTL0 */
  556. MSDC_WRITE32(MSDC_TOP_BASE + 0xC, 0x0); /* EMMC50_PAD_DS_TUNE */
  557. } else if ((id == 0) && (div == 0) && (host->src_clk==364000000)) {
  558. } else if (id == 0) {
  559. /* FIX ME, f0, f4 nore more used */
  560. MSDC_SET_FIELD(host->base + 0xb0, (0x7 <<7), 0x0); /* PATCH_BIT0[MSDC_PB0_INT_DAT_LATCH_CK_SEL] */
  561. MSDC_SET_FIELD(host->base + 0xb0, (0x1 <<3), 0x0);
  562. MSDC_SET_FIELD(host->base + 0xb4, (0x7 <<3), 0x0); /* PATCH_BIT1[MSDC_PB1_CMD_RSP_TA_CNTR] */
  563. MSDC_SET_FIELD(host->base + 0xb4, (0x7 <<0), 0x0); /* PATCH_BIT1[MSDC_PB1_WRDAT_CRCS_TA_CNTR] */
  564. MSDC_SET_FIELD(host->base + 0xb8, (0x7 << 29), AUTOK_CRC_LATCH_EN_HS_VALUE);
  565. MSDC_SET_FIELD(host->base + 0xb8, (0x7 << 16), AUTOK_CMD_LATCH_EN_HS_VALUE);
  566. MSDC_SET_FIELD(host->base + 0x4, (0x1 << 1), 0x0); /*MSDC_IOCON[MSDC_IOCON_RSPL] */
  567. MSDC_SET_FIELD(host->base + 0x4, (0x1 << 2), 0x0); /* MSDC_IOCON[MSDC_IOCON_R_D_SMPL] */
  568. //MSDC_SET_FIELD(host->base + 0xf0, (0x3f << 16), 0x24); /* PAD_TUNE[MSDC_PAD_TUNE_CMDRDLY] */
  569. //MSDC_SET_FIELD(host->base + 0xf4, (0x3f << 16), 0x0); /* PAD_TUNE[MSDC_PAD_TUNE_CMDRRDLY] */
  570. //MSDC_SET_FIELD(host->base + 0xf0, (0x3f << 8), 0x24); /* PAD_TUNE[MSDC_PAD_TUNE_DATRDLY] */
  571. //MSDC_SET_FIELD(host->base + 0xf4, (0x3f << 8), 0x0); /* PAD_TUNE[MSDC_PAD_TUNE_DATRRDLY] */
  572. } else if ((id == 1) && (mode == 1) && (host->src_clk==182000000)) {
  573. MSDC_SET_FIELD(host->base + 0x4, (0x1 << 1), 0x1); /*MSDC_IOCON[MSDC_IOCON_RSPL] */
  574. MSDC_SET_FIELD(host->base + 0xb0, (0x1 << 3), 0x1);
  575. MSDC_SET_FIELD(host->base + 0xb8, (0x7 << 29), AUTOK_CMD_LATCH_EN_SDR104_PORT1_VALUE);
  576. MSDC_SET_FIELD(host->base + 0xb8, (0x7 << 16), AUTOK_CMD_LATCH_EN_SDR104_PORT1_VALUE);
  577. MSDC_SET_FIELD(host->base + 0xb8, (0x1 << 25), 0x1);
  578. MSDC_SET_FIELD(host->base + 0xf0, (0x1 << 21), 0x1);
  579. MSDC_SET_FIELD(host->base + 0xf0, (0x1f << 16), 0x1);
  580. MSDC_SET_FIELD(host->base + 0xf0, (0x1 << 13), 0x1);
  581. MSDC_SET_FIELD(host->base + 0xf0, (0x1f << 8), 0x1);
  582. } else if (id == 1 && div == 0 && host->src_clk==156000000) {
  583. }
  584. }
  585. }
  586. #endif