mmc_common_inter.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  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) 2018. 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. #include "mmc_common_inter.h"
  34. #if defined(MMC_MSDC_DRV_LK)
  35. #include "block_generic_interface.h"
  36. #include "mt_gpt.h"
  37. #include "storage_api.h"
  38. #endif
  39. #ifdef MTK_EMMC_SUPPORT_OTP
  40. #include <platform/errno.h>
  41. #include <part_interface.h>
  42. #include <part_status.h>
  43. #endif
  44. #if !defined(MMC_MSDC_DRV_CTP)
  45. #define MMC_HOST_ID 0
  46. #define BUF_BLK_NUM 4 /* 4 * 512bytes = 2KB */
  47. /**************************************************************************
  48. * DEBUG CONTROL
  49. **************************************************************************/
  50. /**************************************************************************
  51. * MACRO DEFINITION
  52. **************************************************************************/
  53. /**************************************************************************
  54. * EXTERNAL DECLARATION
  55. **************************************************************************/
  56. static int mmc_do_erase(int dev_num, u64 start_addr, u64 len, u32 part_id);
  57. #if defined(MMC_MSDC_DRV_PRELOADER)
  58. extern struct nand_chip g_nand_chip;
  59. static blkdev_t g_mmc_bdev;
  60. #endif
  61. #if defined(MMC_MSDC_DRV_LK)
  62. u64 g_emmc_size = 0;
  63. #endif
  64. u64 g_emmc_user_size = 0;
  65. int mmc_switch_part(u32 part_id)
  66. {
  67. int err = MMC_ERR_NONE;
  68. #ifdef MTK_EMMC_SUPPORT
  69. struct mmc_card *card;
  70. struct mmc_host *host;
  71. u8 cfg;
  72. u8 part = (u8)part_id;
  73. u8 *ext_csd;
  74. card = mmc_get_card(MMC_HOST_ID);
  75. host = mmc_get_host(MMC_HOST_ID);
  76. if (!card)
  77. return MMC_ERR_INVALID;
  78. ext_csd = &card->raw_ext_csd[0];
  79. if (mmc_card_mmc(card) && ext_csd[EXT_CSD_REV] >= 3) {
  80. if (part_id >= EMMC_PART_END){
  81. err = MMC_ERR_FAILED;
  82. goto out;
  83. }
  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, MMC_SWITCH_MODE_WRITE_BYTE);
  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. out:
  100. if (err)
  101. msdc_pr_err("[%s]: failed to switch part_id:%d, err=%d\n", __func__, part_id, err);
  102. #endif
  103. return err;
  104. }
  105. static u64 mmc_get_emmc_size(struct mmc_card *card)
  106. {
  107. u64 size_tmp = 0ULL;
  108. size_tmp += card->ext_csd.boot_part_sz * 2;
  109. size_tmp += card->ext_csd.rpmb_sz;
  110. size_tmp += 1024 *
  111. (card->ext_csd.gp_sz_kb[0] + card->ext_csd.gp_sz_kb[1] + card->ext_csd.gp_sz_kb[2] + card->ext_csd.gp_sz_kb[3]);
  112. size_tmp += (u64)card->blklen * card->nblks;
  113. return size_tmp;
  114. }
  115. int mmc_get_boot_part(u32 *bootpart)
  116. {
  117. struct mmc_card *card;
  118. struct mmc_host *host;
  119. int err = MMC_ERR_NONE;
  120. u8 *ext_csd;
  121. u8 part_config;
  122. if (!bootpart)
  123. return -1;
  124. card = mmc_get_card(MMC_HOST_ID);
  125. host = mmc_get_host(MMC_HOST_ID);
  126. if (!card || !host)
  127. return -1;
  128. err = mmc_read_ext_csd(host, card);
  129. if (err == MMC_ERR_NONE) {
  130. ext_csd = &card->raw_ext_csd[0];
  131. part_config = (ext_csd[EXT_CSD_PART_CFG] >> 3) & 0x07;
  132. if (part_config == 1) {
  133. *bootpart = EMMC_PART_BOOT1;
  134. } else if (part_config == 2) {
  135. *bootpart = EMMC_PART_BOOT2;
  136. } else if (part_config == 7) {
  137. *bootpart = EMMC_PART_USER;
  138. } else {
  139. msdc_pr_err("[PL MTK] fail to get boot part\n");
  140. return -1;
  141. }
  142. }
  143. return err;
  144. }
  145. int mmc_set_boot_part(u32 bootpart)
  146. {
  147. struct mmc_card *card;
  148. struct mmc_host *host;
  149. int err = MMC_ERR_NONE;
  150. u8 part_config;
  151. u8 cur_bootpart;
  152. if (bootpart != EMMC_PART_BOOT1
  153. && bootpart != EMMC_PART_BOOT2
  154. && bootpart != EMMC_PART_USER)
  155. return -1;
  156. card = mmc_get_card(MMC_HOST_ID);
  157. host = mmc_get_host(MMC_HOST_ID);
  158. if (!card || !host)
  159. return -1;
  160. err = mmc_read_ext_csd(host, card);
  161. if (err != MMC_ERR_NONE)
  162. goto out;
  163. part_config = card->raw_ext_csd[EXT_CSD_PART_CFG];
  164. cur_bootpart = (part_config >> 3) & 0x7;
  165. if (((u32)cur_bootpart) == bootpart)
  166. goto out;
  167. msdc_pr_info("[SD0] Current boot part is %d\n", cur_bootpart);
  168. part_config = (part_config & (~(0x7 << 3))) | (bootpart << 3);
  169. msdc_pr_info("[SD0] Set boot part as %d\n", bootpart);
  170. err = mmc_switch(host, card,
  171. EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CFG, part_config, MMC_SWITCH_MODE_WRITE_BYTE);
  172. out:
  173. return err;
  174. }
  175. #if defined(MMC_MSDC_DRV_PRELOADER)
  176. static int mmc_bread(blkdev_t *bdev, u32 blknr, u32 blks, u8 *buf, u32 part_id)
  177. {
  178. struct mmc_host *host = (struct mmc_host*)bdev->priv;
  179. mmc_switch_part(part_id);
  180. return mmc_block_read(host->id, (unsigned long)blknr, blks, (unsigned long*)buf);
  181. }
  182. static int mmc_bwrite(blkdev_t *bdev, u32 blknr, u32 blks, u8 *buf, u32 part_id)
  183. {
  184. struct mmc_host *host = (struct mmc_host*)bdev->priv;
  185. mmc_switch_part(part_id);
  186. return mmc_block_write(host->id, (unsigned long)blknr, blks, (unsigned long*)buf);
  187. }
  188. // ==========================================================
  189. // MMC Common Interface - Init
  190. // ==========================================================
  191. u32 mmc_init_device(void)
  192. {
  193. int ret;
  194. struct mmc_card *card;
  195. if (!blkdev_get(BOOTDEV_SDMMC)) {
  196. ret = mmc_init(MMC_HOST_ID, MSDC_MODE_DEFAULT);
  197. if (ret != 0) {
  198. msdc_pr_err("[SD0] init card failed\n");
  199. return ret;
  200. }
  201. #if defined(SLT)
  202. msdc_apply_timing(MMC_HOST_ID);
  203. #endif
  204. memset(&g_mmc_bdev, 0, sizeof(blkdev_t));
  205. card = mmc_get_card(MMC_HOST_ID);
  206. g_mmc_bdev.blksz = MMC_BLOCK_SIZE;
  207. g_mmc_bdev.erasesz = MMC_BLOCK_SIZE;
  208. g_mmc_bdev.blks = card->nblks;
  209. g_mmc_bdev.bread = mmc_bread;
  210. g_mmc_bdev.bwrite = mmc_bwrite;
  211. g_mmc_bdev.type = BOOTDEV_SDMMC;
  212. g_mmc_bdev.blkbuf = NULL;
  213. g_mmc_bdev.priv = (void*)mmc_get_host(MMC_HOST_ID);
  214. g_mmc_bdev.offset = mmc_get_emmc_size(card) / MMC_BLOCK_SIZE; /* in blksz unit */
  215. g_emmc_user_size = (u64)card->blklen * card->nblks;
  216. blkdev_register(&g_mmc_bdev);
  217. }
  218. return 0;
  219. }
  220. #if defined(FEATURE_EMCP)
  221. u32 mmc_get_device_id(u8 *id, u32 len,u32 *fw_len)
  222. {
  223. u8 buf[16]; /* CID = 128 bits */
  224. struct mmc_card *card;
  225. u8 buf_sanid[512];
  226. u8 i;
  227. if (0 != mmc_init_device())
  228. return -1;
  229. card = mmc_get_card(MMC_HOST_ID);
  230. buf[0] = (card->raw_cid[0] >> 24) & 0xFF; /* Manufacturer ID */
  231. buf[1] = (card->raw_cid[0] >> 16) & 0xFF; /* Reserved(6)+Card/BGA(2) */
  232. buf[2] = (card->raw_cid[0] >> 8 ) & 0xFF; /* OEM/Application ID */
  233. buf[3] = (card->raw_cid[0] >> 0 ) & 0xFF; /* Product name [0] */
  234. buf[4] = (card->raw_cid[1] >> 24) & 0xFF; /* Product name [1] */
  235. buf[5] = (card->raw_cid[1] >> 16) & 0xFF; /* Product name [2] */
  236. buf[6] = (card->raw_cid[1] >> 8 ) & 0xFF; /* Product name [3] */
  237. buf[7] = (card->raw_cid[1] >> 0 ) & 0xFF; /* Product name [4] */
  238. buf[8] = (card->raw_cid[2] >> 24) & 0xFF; /* Product name [5] */
  239. buf[9] = (card->raw_cid[2] >> 16) & 0xFF; /* Product revision */
  240. buf[10] =(card->raw_cid[2] >> 8 ) & 0xFF; /* Serial Number [0] */
  241. buf[11] =(card->raw_cid[2] >> 0 ) & 0xFF; /* Serial Number [1] */
  242. buf[12] =(card->raw_cid[3] >> 24) & 0xFF; /* Serial Number [2] */
  243. buf[13] =(card->raw_cid[3] >> 16) & 0xFF; /* Serial Number [3] */
  244. buf[14] =(card->raw_cid[3] >> 8 ) & 0xFF; /* Manufacturer date */
  245. buf[15] =(card->raw_cid[3] >> 0 ) & 0xFF; /* CRC7 + stuff bit*/
  246. *fw_len = 1;
  247. /* sandisk */
  248. if (buf[0] == 0x45) {
  249. /* before v4.41 */
  250. if (card->raw_ext_csd[EXT_CSD_REV] <= 5) {
  251. if (0 == mmc_get_sandisk_fwid(MMC_HOST_ID,buf_sanid)) {
  252. *fw_len = 6;
  253. }
  254. } else if (card->raw_ext_csd[EXT_CSD_REV] == 6) { /* v4.5, v4.51 */
  255. /* do nothing, same as other vendor */
  256. } else if (card->raw_ext_csd[EXT_CSD_REV] == 7) { /* v5.0 */
  257. /* sandisk only use 6 bytes */
  258. *fw_len = 6;
  259. for (i=0; i<6; i++) {
  260. buf_sanid[32+i] = card->raw_ext_csd[EXT_CSD_FIRMWARE_VERSION+i];
  261. }
  262. }
  263. }
  264. len = len > 16 ? 16 : len;
  265. memcpy(id, buf, len);
  266. if (*fw_len == 6)
  267. memcpy(id+len,buf_sanid+32,6);
  268. else
  269. *(id+len) = buf[9];
  270. #if defined(MMC_MSDC_DRV_PRELOADER)
  271. msdc_pr_err("eMMC cid: %x,%x,%x,%x\n", card->raw_cid[0], card->raw_cid[1],
  272. card->raw_cid[2], card->raw_cid[3]);
  273. #endif
  274. return 0;
  275. }
  276. #endif
  277. #if defined(FEATURE_MMC_BOOT_ACCESS)
  278. int mmc_bread_boot(blkdev_t *bdev, u32 blknr, u32 blks, u8 *buf)
  279. {
  280. u32 pid, id;
  281. struct mmc_host *host;
  282. if (bdev && bdev->priv) {
  283. host = (struct mmc_host*)bdev->priv;
  284. id = host->id;
  285. } else {
  286. msdc_pr_err("[%s]: invalid bdev, force the host id to 0\n", __func__);
  287. id = 0;
  288. }
  289. if (mmc_get_boot_part(&pid)) {
  290. msdc_pr_err("[%s]: invalid pid=%d\n", __func__, pid);
  291. return -1;
  292. }
  293. mmc_switch_part(pid);
  294. return mmc_block_read(id, (unsigned long)blknr, blks, (unsigned long*)buf);
  295. }
  296. int mmc_bwrite_boot(blkdev_t *bdev, u32 blknr, u32 blks, u8 *buf)
  297. {
  298. u32 pid, id;
  299. struct mmc_host *host;
  300. if (bdev && bdev->priv) {
  301. host = (struct mmc_host*)bdev->priv;
  302. id = host->id;
  303. } else {
  304. id = 0;
  305. }
  306. if (mmc_get_boot_part(&pid)) {
  307. msdc_pr_err("[%s]: invalid pid=%d\n", __func__, pid);
  308. return -1;
  309. }
  310. mmc_switch_part(pid);
  311. return mmc_block_write(id, (unsigned long)blknr, blks, (unsigned long*)buf);
  312. }
  313. #endif
  314. #endif //#if defined(MMC_MSDC_DRV_PRELOADER)
  315. #if defined(MMC_MSDC_DRV_LK)
  316. #include "part_dev.h"
  317. static block_dev_desc_t sd_dev[MSDC_MAX_NUM];
  318. static int boot_dev_found = 0;
  319. static part_dev_t boot_dev;
  320. unsigned long mmc_wrap_bread(int dev_num, unsigned long blknr, lbaint_t blkcnt, void *dst, unsigned int part_id)
  321. {
  322. unsigned long ret;
  323. #ifdef LK_PROFILING
  324. unsigned long t1, t2;
  325. t1 = get_timer(0);
  326. #endif
  327. mmc_switch_part(part_id);
  328. if (mmc_block_read(dev_num, blknr, blkcnt, (unsigned long *)dst) == MMC_ERR_NONE)
  329. ret = blkcnt;
  330. else
  331. ret = (unsigned long) -1;
  332. #ifdef LK_PROFILING
  333. t2 = get_timer(t1);
  334. msdc_pr_err("[PROFILE] mmc read %lu blks in %lu ms: %luKB/s\n", blkcnt, t2, blkcnt * 500 / t2);
  335. #endif
  336. return ret;
  337. }
  338. unsigned long mmc_wrap_bwrite(int dev_num, unsigned long blknr, lbaint_t blkcnt, const void *src, unsigned int part_id)
  339. {
  340. unsigned long ret;
  341. #ifdef LK_PROFILING
  342. unsigned long t1, t2;
  343. t1 = get_timer(0);
  344. #endif
  345. mmc_switch_part(part_id);
  346. if (mmc_block_write(dev_num, blknr, blkcnt, (unsigned long *)src) == MMC_ERR_NONE)
  347. ret = blkcnt;
  348. else
  349. ret = (unsigned long) -1;
  350. #ifdef LK_PROFILING
  351. t2 = get_timer(t1);
  352. msdc_pr_err("[PROFILE] mmc write %lu blks in %lu ms: %luKB/s\n", blkcnt, t2, blkcnt * 500 / t2);
  353. #endif
  354. return ret;
  355. }
  356. #ifdef MTK_EMMC_SUPPORT_OTP
  357. /* there are atmost 4 write protectioin groups in current OTP solution.
  358. each wp group size denpends on emmc device, but usually it is 8MB or 4MB.
  359. OTP partition total size is 43MB,plus the extra 8MB aligned space.
  360. So we can ensure to have 4 wp groups in the case of 8MB WP group size.
  361. Each wp group can be accessed and locked independently.
  362. */
  363. u32 mmc_wrap_otp_get_size(u32 group_id)
  364. {
  365. struct mmc_card *card = mmc_get_card(MMC_HOST_ID);
  366. if(!card || !mmc_card_mmc(card))
  367. goto out;
  368. if (card->csd.mmca_vsn < CSD_SPEC_VER_4){
  369. msdc_pr_err("emmc version is below 4!\n");
  370. goto out;
  371. }
  372. /* check wp support in this emmc */
  373. if (card->csd.write_prot_grp == 0){
  374. msdc_pr_err("write project not support in this emmc!\n");
  375. goto out;
  376. }
  377. return card->wp_size * 512;
  378. out:
  379. return 0;
  380. }
  381. u32 mmc_wrap_otp_lock(u32 group_id)
  382. {
  383. int err = MMC_ERR_NONE;
  384. int start_sect = 0;
  385. uint32 l_otp_start_addr;
  386. struct mmc_card *card = mmc_get_card(MMC_HOST_ID);
  387. if (group_id > 3) {
  388. msdc_pr_err("[OTP]wp group_id is out of scope.\n");
  389. err = MMC_ERR_INVALID;
  390. goto out;
  391. }
  392. if (partition_exists("otp") != PART_OK) {
  393. msdc_pr_err("[OTP]fail to find partition otp\n");
  394. err = MMC_ERR_FAILED;
  395. goto out;
  396. }
  397. if (storage_get_blksz() == 0) {
  398. msdc_pr_err("[OTP] invalid blksz\n");
  399. err = MMC_ERR_FAILED;
  400. goto out;
  401. }
  402. start_sect = partition_get_offset_by_name("otp") / storage_get_blksz();
  403. msdc_pr_err("otp part->start_sect: %d\n", start_sect);
  404. l_otp_start_addr = mmc_otp_start(MMC_HOST_ID, start_sect);
  405. if ((l_otp_start_addr + (group_id+1) * card->wp_size) > (start_sect + (partition_get_size_by_name("otp") / storage_get_blksz())))
  406. {
  407. msdc_pr_err("wp group size is too large: 0x%x, can not supply multiple groups\n", card->wp_size * 512);
  408. err = MMC_ERR_INVALID;
  409. goto out;
  410. }
  411. mmc_switch_part(partition_get_region_by_name("otp"));
  412. err = mmc_otp_lock(MMC_HOST_ID, l_otp_start_addr + group_id * card->wp_size, card->wp_size, partition_get_region_by_name("otp"));
  413. if (err){
  414. msdc_pr_err("mmc_otp_lock return 0x%x\n", err);
  415. goto out;
  416. }
  417. out:
  418. return err;
  419. }
  420. u32 mmc_wrap_otp_status(u32 group_id, u32 *status)
  421. {
  422. int err = MMC_ERR_NONE;
  423. uint32 l_otp_start_addr;
  424. struct mmc_card *card = mmc_get_card(MMC_HOST_ID);
  425. int start_sect = 0;
  426. if (group_id > 3) {
  427. msdc_pr_err("[OTP]wp group_id is out of scope.\n");
  428. err = MMC_ERR_INVALID;
  429. goto out;
  430. }
  431. if (NULL == status)
  432. {
  433. msdc_pr_err("[OTP]error, status parameter is NULL\n");
  434. err = MMC_ERR_INVALID;
  435. goto out;
  436. }
  437. if (partition_exists("otp") != PART_OK) {
  438. msdc_pr_err("[OTP]fail to find partition otp\n");
  439. err = MMC_ERR_FAILED;
  440. goto out;
  441. }
  442. if (storage_get_blksz() == 0) {
  443. msdc_pr_err("[OTP] invalid blksz\n");
  444. err = MMC_ERR_FAILED;
  445. goto out;
  446. }
  447. start_sect = partition_get_offset_by_name("otp") / storage_get_blksz();
  448. l_otp_start_addr = mmc_otp_start(MMC_HOST_ID, start_sect);
  449. if ((l_otp_start_addr + (group_id+1) * card->wp_size) > (start_sect + (partition_get_size_by_name("otp") / storage_get_blksz())))
  450. {
  451. msdc_pr_err("wp group size is too large: 0x%x, can not supply multiple groups\n", card->wp_size * 512);
  452. err = MMC_ERR_INVALID;
  453. goto out;
  454. }
  455. mmc_switch_part(partition_get_region_by_name("otp"));
  456. err = mmc_otp_status(MMC_HOST_ID, l_otp_start_addr + group_id * card->wp_size, card->wp_size, status);
  457. if (err){
  458. msdc_pr_err("mmc_otp_status return 0x%x\n", err);
  459. goto out;
  460. }
  461. out:
  462. return err;
  463. }
  464. int mmc_wrap_otp_write(u32 group_id, u64 offset, uchar *buf, u64 size)
  465. {
  466. part_dev_t *dev;
  467. struct mmc_card *card = mmc_get_card(MMC_HOST_ID);
  468. u32 l_otp_start_addr;
  469. u64 group_start;
  470. u32 lock_stat;
  471. u64 addr;
  472. int start_sect = 0;
  473. if (group_id > 3 || NULL == buf || (offset+size) > card->wp_size * 512ULL) {
  474. msdc_pr_err("[OTP]Parameter invalid, group_id: %d, offset: %llu, buf: %p, size: %llu\n",
  475. group_id, offset, buf, size);
  476. return -MMC_ERR_INVALID;
  477. }
  478. if (size == 0)
  479. return 0;
  480. if (mmc_wrap_otp_status(group_id, &lock_stat) != MMC_ERR_NONE)
  481. {
  482. return -MMC_ERR_FAILED;
  483. }
  484. if (lock_stat != EMMC_OTP_UNLOCKED)
  485. {
  486. msdc_pr_err("[OTP]Can not write locked group\n");
  487. return -MMC_ERR_WP_VIOLATION;
  488. }
  489. if (partition_exists("otp") != PART_OK) {
  490. msdc_pr_err("[OTP]fail to find partition otp\n");
  491. return -MMC_ERR_FAILED;
  492. }
  493. if (storage_get_blksz() == 0) {
  494. msdc_pr_err("[OTP] invalid blksz\n");
  495. return -MMC_ERR_FAILED;
  496. }
  497. start_sect = partition_get_offset_by_name("otp") / storage_get_blksz();
  498. l_otp_start_addr = mmc_otp_start(MMC_HOST_ID, start_sect);
  499. if ((l_otp_start_addr + (group_id+1) * card->wp_size) > (start_sect + (partition_get_size_by_name("otp") / storage_get_blksz())))
  500. {
  501. msdc_pr_err("wp group size is too large: 0x%x, can not supply multiple groups\n", card->wp_size * 512);
  502. return -MMC_ERR_INVALID;
  503. }
  504. group_start = (l_otp_start_addr + group_id*card->wp_size) * 512ULL;
  505. addr = offset + group_start;
  506. dev = mt_part_get_device();
  507. if (!dev) {
  508. msdc_pr_err("dev = NULL\n");
  509. return -ENODEV;
  510. }
  511. return dev->write(dev, buf, addr, size, partition_get_region_by_name("otp"));
  512. }
  513. int mmc_wrap_otp_read(u32 group_id, u64 offset, uchar *buf, u64 size)
  514. {
  515. part_dev_t *dev;
  516. struct mmc_card *card = mmc_get_card(MMC_HOST_ID);
  517. uint32 l_otp_start_addr;
  518. u64 group_start;
  519. u64 addr;
  520. int start_sect = 0;
  521. if (group_id > 3 || NULL == buf || (offset+size) > card->wp_size * 512ULL) {
  522. msdc_pr_err("[OTP]Parameter invalid.\n");
  523. return -MMC_ERR_INVALID;
  524. }
  525. if (size == 0)
  526. return 0;
  527. if (partition_exists("otp") != PART_OK) {
  528. msdc_pr_err("[OTP]fail to find partition otp\n");
  529. return -MMC_ERR_FAILED;
  530. }
  531. if (storage_get_blksz() == 0) {
  532. msdc_pr_err("[OTP] invalid blksz\n");
  533. return -MMC_ERR_FAILED;
  534. }
  535. start_sect = partition_get_offset_by_name("otp") / storage_get_blksz();
  536. l_otp_start_addr = mmc_otp_start(MMC_HOST_ID, start_sect);
  537. if ((l_otp_start_addr + (group_id+1) * card->wp_size) > (start_sect + (partition_get_size_by_name("otp") / storage_get_blksz())))
  538. {
  539. msdc_pr_err("wp group size is too large: 0x%x, can not supply multiple groups\n", card->wp_size*512);
  540. return -MMC_ERR_INVALID;
  541. }
  542. group_start = (l_otp_start_addr + group_id*card->wp_size) * 512ULL;
  543. addr = offset + group_start;
  544. dev = mt_part_get_device();
  545. if (!dev) {
  546. msdc_pr_err("dev = NULL\n");
  547. return -ENODEV;
  548. }
  549. return dev->read(dev, addr, buf, size, partition_get_region_by_name("otp"));
  550. }
  551. #endif /* MTK_EMMC_SUPPORT_OTP */
  552. int mmc_legacy_init(int verbose)
  553. {
  554. int id = verbose - 1;
  555. int err = MMC_ERR_NONE;
  556. struct mmc_host *host;
  557. struct mmc_card *card;
  558. block_dev_desc_t *bdev;
  559. u8 *ext_csd;
  560. bdev = &sd_dev[id];
  561. //msdc_hard_reset(host);
  562. err = mmc_init(id, MSDC_MODE_DEFAULT);
  563. if (err == MMC_ERR_NONE && !boot_dev_found) {
  564. /* fill in device description */
  565. card=mmc_get_card(id);
  566. host=mmc_get_host(id);
  567. g_emmc_size = mmc_get_emmc_size(card);
  568. g_emmc_user_size = (u64)card->blklen * card->nblks;
  569. bdev->dev = id;
  570. bdev->type = BOOTDEV_SDMMC;
  571. bdev->blksz = MMC_BLOCK_SIZE;
  572. ext_csd = &card->raw_ext_csd[0];
  573. if (ext_csd[EXT_CSD_ERASE_GRP_DEF] & EXT_CSD_ERASE_GRP_DEF_EN)
  574. bdev->erasesz = card->ext_csd.hc_erase_grp_sz * 512 * 1024;
  575. else
  576. bdev->erasesz = card->csd.erase_sctsz * 512;
  577. bdev->lba = card->nblks * card->blklen / MMC_BLOCK_SIZE;
  578. bdev->blk_bits = 9;
  579. bdev->part_boot1 = EMMC_PART_BOOT1;
  580. bdev->part_boot2 = EMMC_PART_BOOT2;
  581. bdev->part_user = EMMC_PART_USER;
  582. bdev->block_read = mmc_wrap_bread;
  583. bdev->block_write = mmc_wrap_bwrite;
  584. #if defined(MEM_PRESERVED_MODE_ENABLE)
  585. if (id==1) {
  586. host->boot_type = NON_BOOTABLE;
  587. return err;
  588. }
  589. #endif
  590. host->boot_type = RAW_BOOT;
  591. /* FIXME. only one RAW_BOOT dev */
  592. if (host->boot_type == RAW_BOOT) {
  593. boot_dev.id = id;
  594. boot_dev.init = 1;
  595. boot_dev.blkdev = bdev;
  596. boot_dev.erase = mmc_do_erase;
  597. mt_part_register_device(&boot_dev);
  598. boot_dev_found = 1;
  599. msdc_pr_info("[SD%d] boot device found\n", id);
  600. } else if (host->boot_type == FAT_BOOT) {
  601. #if (CONFIG_COMMANDS & CFG_CMD_FAT)
  602. if (0 == fat_register_device(bdev, 1)) {
  603. boot_dev_found = 1;
  604. msdc_pr_info("[SD%d] FAT partition found\n", id);
  605. }
  606. #endif
  607. }
  608. }
  609. #ifdef MTK_EMMC_SUPPORT_OTP
  610. /* uncomment for otp UT, WARNING: MUST BE HERE BECAUSE OF PARTITION INFO HAVING INITED HERE. */
  611. //mmc_otp_test();
  612. #endif
  613. return err;
  614. }
  615. // ==========================================================
  616. // MMC Common Interface - Erase
  617. // ==========================================================
  618. static int __mmc_do_erase(struct mmc_host *host,struct mmc_card *card, u64 start_addr, u64 len)
  619. {
  620. int err = MMC_ERR_NONE;
  621. u64 end_addr =((start_addr + len + card->blklen - 1)/card->blklen - 1) * card->blklen;
  622. u8 buf[512];
  623. if (end_addr/card->blklen > card->nblks - 1) {
  624. msdc_pr_err("[MSDC%d]Erase address out of range! start<0x%llx>,len<0x%llx>,card_nblks<0x%x>\n",
  625. host->id, start_addr, len, card->nblks);
  626. return MMC_ERR_INVALID;
  627. }
  628. resend:
  629. err = mmc_erase_start(card, start_addr);
  630. if (err != MMC_ERR_NONE) {
  631. msdc_pr_err("[MSDC%d]Set erase start addrees 0x%llx failed,Err<%d>\n", host->id, start_addr, err);
  632. if (err == MMC_ERR_ERASE_SEQ) {
  633. msdc_pr_err("[MSDC%d]Erase sequence error, retry erase.\n", host->id);
  634. goto dummy_read;
  635. } else {
  636. goto out;
  637. }
  638. }
  639. err = mmc_erase_end(card, end_addr);
  640. if (err != MMC_ERR_NONE) {
  641. msdc_pr_err("[MSDC%d]Set erase end addrees 0x%llx + 0x%llx failed,Err<%d>\n", host->id, start_addr, len, err);
  642. if (err == MMC_ERR_ERASE_SEQ) {
  643. msdc_pr_err("[MSDC%d]Erase sequence error, retry erase.\n", host->id);
  644. goto dummy_read;
  645. } else {
  646. goto out;
  647. }
  648. }
  649. err = mmc_erase(card, MMC_ERASE_TRIM);
  650. if (err != MMC_ERR_NONE) {
  651. msdc_pr_err("[MSDC%d]Set erase <0x%llx - 0x%llx> failed,Err<%d>\n", host->id, start_addr, start_addr + len, err);
  652. goto out;
  653. }
  654. msdc_pr_info("[MSDC%d]0x%llx - 0x%llx Erased\n", host->id, start_addr, start_addr + len);
  655. out:
  656. return err;
  657. dummy_read:
  658. /* Add dummy read to reset erase sequence error. */
  659. err = mmc_block_read(host->id, 0, 1, (unsigned long*)buf);
  660. if (err != MMC_ERR_NONE) {
  661. msdc_pr_err("[MSDC%d]Fail in read card\n", host->id);
  662. goto out;
  663. }
  664. goto resend;
  665. }
  666. int mmc_do_erase(int dev_num, u64 start_addr, u64 len, u32 part_id)
  667. {
  668. struct mmc_host *host = mmc_get_host(dev_num);
  669. struct mmc_card *card = mmc_get_card(dev_num);
  670. //struct mmc_erase_part erase_part[EMMC_PART_END];
  671. u32 err;
  672. if (!card || !host) {
  673. msdc_pr_err("[mmc_do_erase] card or host is NULL\n");
  674. return MMC_ERR_INVALID;
  675. }
  676. if (!len) {
  677. msdc_pr_err("[MSDC%d] invalid erase size! len<0x%llx>\n",host->id,len);
  678. return MMC_ERR_INVALID;
  679. }
  680. if ((start_addr % card->blklen) || (len % card->blklen)) {
  681. msdc_pr_err("[MSDC%d] non-alignment erase address! start<0x%llx>,len<0x%llx>,card_nblks<0x%x>\n",
  682. host->id, start_addr, len, card->nblks);
  683. return MMC_ERR_INVALID;
  684. }
  685. if ((err = mmc_switch_part(part_id))) {
  686. msdc_pr_err("[MSDC%d] mmc swtich failed.part<%d> error <%d> \n", host->id, part_id, err);
  687. return err;
  688. }
  689. if ((err = __mmc_do_erase(host, card, start_addr, len))) {
  690. msdc_pr_err("[MSDC%d] mmc erase failed.error <%d> \n",host->id, err);
  691. return err;
  692. }
  693. return err;
  694. }
  695. #endif // #if defined(MMC_MSDC_DRV_LK)
  696. #endif //!defined(MMC_MSDC_DRV_CTP)