mmc_common_inter.c 23 KB

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