mt_emi_bm.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. #include <linux/kernel.h>
  2. #include <mt-plat/sync_write.h>
  3. #include <linux/of.h>
  4. #include <linux/of_address.h>
  5. #include <mt-plat/mt_io.h>
  6. #include "mach/mt_emi_bm.h"
  7. static unsigned char g_cBWL;
  8. static void __iomem *EMI_BASE_ADDR; /* not initialise statics to 0 or NULL */
  9. void BM_Init(void)
  10. {
  11. struct device_node *node;
  12. /* DTS version */
  13. node = of_find_compatible_node(NULL, NULL, "mediatek,EMI");
  14. if (node) {
  15. EMI_BASE_ADDR = of_iomap(node, 0);
  16. pr_err("get EMI_BASE_ADDR @ %p\n", EMI_BASE_ADDR);
  17. } else {
  18. pr_err("can't find compatible node\n");
  19. return;
  20. }
  21. g_cBWL = 0;
  22. /*
  23. * make sure BW limiter counts consumed Soft-mode BW of each master
  24. */
  25. if (readl(IOMEM(EMI_ARBA)) & 0x00008000) {
  26. g_cBWL |= 1 << 0;
  27. mt_reg_sync_writel(readl(IOMEM(EMI_ARBA)) &
  28. ~0x00008000, EMI_ARBA);
  29. }
  30. if (readl(IOMEM(EMI_ARBB)) & 0x00008000) {
  31. g_cBWL |= 1 << 1;
  32. mt_reg_sync_writel(readl(IOMEM(EMI_ARBB)) &
  33. ~0x00008000, EMI_ARBB);
  34. }
  35. if (readl(IOMEM(EMI_ARBC)) & 0x00008000) {
  36. g_cBWL |= 1 << 2;
  37. mt_reg_sync_writel(readl(IOMEM(EMI_ARBC)) &
  38. ~0x00008000, EMI_ARBC);
  39. }
  40. if (readl(IOMEM(EMI_ARBD)) & 0x00008000) {
  41. g_cBWL |= 1 << 3;
  42. mt_reg_sync_writel(readl(IOMEM(EMI_ARBD)) &
  43. ~0x00008000, EMI_ARBD);
  44. }
  45. if (readl(IOMEM(EMI_ARBE)) & 0x00008000) {
  46. g_cBWL |= 1 << 4;
  47. mt_reg_sync_writel(readl(IOMEM(EMI_ARBE)) &
  48. ~0x00008000, EMI_ARBE);
  49. }
  50. if (readl(IOMEM(EMI_ARBF)) & 0x00008000) {
  51. g_cBWL |= 1 << 5;
  52. mt_reg_sync_writel(readl(IOMEM(EMI_ARBF)) &
  53. ~0x00008000, EMI_ARBF);
  54. }
  55. if (readl(IOMEM(EMI_ARBG_2ND)) & 0x00008000) {
  56. g_cBWL |= 1 << 6;
  57. mt_reg_sync_writel(readl(IOMEM(EMI_ARBG_2ND)) &
  58. ~0x00008000, EMI_ARBG_2ND);
  59. }
  60. #if defined(CONFIG_ARCH_MT6797)
  61. if (readl(IOMEM(EMI_ARBG)) & 0x00008000) {
  62. g_cBWL |= 1 << 6;
  63. mt_reg_sync_writel(readl(IOMEM(EMI_ARBG)) &
  64. ~0x00008000, EMI_ARBG);
  65. }
  66. if (readl(IOMEM(EMI_ARBH)) & 0x00008000) {
  67. g_cBWL |= 1 << 7;
  68. mt_reg_sync_writel(readl(IOMEM(EMI_ARBH)) &
  69. ~0x00008000, EMI_ARBH);
  70. }
  71. #endif
  72. }
  73. void BM_DeInit(void)
  74. {
  75. if (g_cBWL & (1 << 0)) {
  76. g_cBWL &= ~(1 << 0);
  77. mt_reg_sync_writel(readl(IOMEM(EMI_ARBA)) |
  78. 0x00008000, EMI_ARBA);
  79. }
  80. if (g_cBWL & (1 << 1)) {
  81. g_cBWL &= ~(1 << 1);
  82. mt_reg_sync_writel(readl(IOMEM(EMI_ARBB)) |
  83. 0x00008000, EMI_ARBB);
  84. }
  85. if (g_cBWL & (1 << 2)) {
  86. g_cBWL &= ~(1 << 2);
  87. mt_reg_sync_writel(readl(IOMEM(EMI_ARBC)) |
  88. 0x00008000, EMI_ARBC);
  89. }
  90. if (g_cBWL & (1 << 3)) {
  91. g_cBWL &= ~(1 << 3);
  92. mt_reg_sync_writel(readl(IOMEM(EMI_ARBD)) |
  93. 0x00008000, EMI_ARBD);
  94. }
  95. if (g_cBWL & (1 << 4)) {
  96. g_cBWL &= ~(1 << 4);
  97. mt_reg_sync_writel(readl(IOMEM(EMI_ARBE)) |
  98. 0x00008000, EMI_ARBE);
  99. }
  100. if (g_cBWL & (1 << 5)) {
  101. g_cBWL &= ~(1 << 5);
  102. mt_reg_sync_writel(readl(IOMEM(EMI_ARBF)) |
  103. 0x00008000, EMI_ARBF);
  104. }
  105. if (g_cBWL & (1 << 6)) {
  106. g_cBWL &= ~(1 << 6);
  107. mt_reg_sync_writel(readl(IOMEM(EMI_ARBG_2ND)) |
  108. 0x00008000, EMI_ARBG_2ND);
  109. }
  110. #if defined(CONFIG_ARCH_MT6797)
  111. if (g_cBWL & (1 << 6)) {
  112. g_cBWL &= ~(1 << 6);
  113. mt_reg_sync_writel(readl(IOMEM(EMI_ARBG)) |
  114. 0x00008000, EMI_ARBG);
  115. }
  116. if (g_cBWL & (1 << 7)) {
  117. g_cBWL &= ~(1 << 7);
  118. mt_reg_sync_writel(readl(IOMEM(EMI_ARBH)) |
  119. 0x00008000, EMI_ARBH);
  120. }
  121. #endif
  122. }
  123. void BM_Enable(const unsigned int enable)
  124. {
  125. const unsigned int value = readl(IOMEM(EMI_BMEN));
  126. mt_reg_sync_writel((value & ~(BUS_MON_PAUSE | BUS_MON_EN)) |
  127. (enable ? BUS_MON_EN : 0), EMI_BMEN);
  128. }
  129. /*
  130. void BM_Disable(void)
  131. {
  132. const unsigned int value = readl(EMI_BMEN);
  133. mt_reg_sync_writel(value & (~BUS_MON_EN), EMI_BMEN);
  134. }
  135. */
  136. void BM_Pause(void)
  137. {
  138. const unsigned int value = readl(IOMEM(EMI_BMEN));
  139. mt_reg_sync_writel(value | BUS_MON_PAUSE, EMI_BMEN);
  140. }
  141. void BM_Continue(void)
  142. {
  143. const unsigned int value = readl(IOMEM(EMI_BMEN));
  144. mt_reg_sync_writel(value & (~BUS_MON_PAUSE), EMI_BMEN);
  145. }
  146. unsigned int BM_IsOverrun(void)
  147. {
  148. /*
  149. * return 0 if EMI_BCNT(bus cycle counts)
  150. * or EMI_WACT(total word counts) is overrun,
  151. * otherwise return an !0 value
  152. */
  153. const unsigned int value = readl(IOMEM(EMI_BMEN));
  154. return value & BC_OVERRUN;
  155. }
  156. void BM_SetReadWriteType(const unsigned int ReadWriteType)
  157. {
  158. const unsigned int value = readl(IOMEM(EMI_BMEN));
  159. /*
  160. * ReadWriteType: 00/11 --> both R/W
  161. * 01 --> only R
  162. * 10 --> only W
  163. */
  164. mt_reg_sync_writel((value & 0xFFFFFFCF) |
  165. (ReadWriteType << 4), EMI_BMEN);
  166. }
  167. int BM_GetBusCycCount(void)
  168. {
  169. return BM_IsOverrun() ? BM_ERR_OVERRUN : readl(IOMEM(EMI_BCNT));
  170. }
  171. unsigned int BM_GetTransAllCount(void)
  172. {
  173. return readl(IOMEM(EMI_TACT));
  174. }
  175. int BM_GetTransCount(const unsigned int counter_num)
  176. {
  177. unsigned int iCount;
  178. switch (counter_num) {
  179. case 1:
  180. iCount = readl(IOMEM(EMI_TSCT));
  181. break;
  182. case 2:
  183. iCount = readl(IOMEM(EMI_TSCT2));
  184. break;
  185. case 3:
  186. iCount = readl(IOMEM(EMI_TSCT3));
  187. break;
  188. default:
  189. return BM_ERR_WRONG_REQ;
  190. }
  191. return iCount;
  192. }
  193. long long BM_GetWordAllCount(void)
  194. {
  195. unsigned int word_all_count;
  196. word_all_count = readl(IOMEM(EMI_WACT));
  197. if (BM_IsOverrun() && (word_all_count == 0xFFFFFFFF))
  198. return BM_ERR_OVERRUN;
  199. else
  200. return word_all_count;
  201. }
  202. int BM_GetWordCount(const unsigned int counter_num)
  203. {
  204. unsigned int iCount;
  205. switch (counter_num) {
  206. case 1:
  207. iCount = readl(IOMEM(EMI_WSCT));
  208. break;
  209. case 2:
  210. iCount = readl(IOMEM(EMI_WSCT2));
  211. break;
  212. case 3:
  213. iCount = readl(IOMEM(EMI_WSCT3));
  214. break;
  215. case 4:
  216. iCount = readl(IOMEM(EMI_WSCT4));
  217. break;
  218. default:
  219. return BM_ERR_WRONG_REQ;
  220. }
  221. return iCount;
  222. }
  223. unsigned int BM_GetBandwidthWordCount(void)
  224. {
  225. return readl(IOMEM(EMI_BACT));
  226. }
  227. unsigned int BM_GetOverheadWordCount(void)
  228. {
  229. return readl(IOMEM(EMI_BSCT));
  230. }
  231. int BM_GetTransTypeCount(const unsigned int counter_num)
  232. {
  233. return (counter_num < 1 || counter_num > BM_COUNTER_MAX) ?
  234. BM_ERR_WRONG_REQ : readl(IOMEM(EMI_TTYPE1 + (counter_num - 1) * 8));
  235. }
  236. int BM_SetMonitorCounter(const unsigned int counter_num,
  237. const unsigned int master, const unsigned int trans_type)
  238. {
  239. unsigned int value;
  240. unsigned long addr;
  241. const unsigned int iMask = 0xFFFF;
  242. if (counter_num < 1 || counter_num > BM_COUNTER_MAX)
  243. return BM_ERR_WRONG_REQ;
  244. if (counter_num == 1) {
  245. addr = (unsigned long) EMI_BMEN;
  246. value = (readl(IOMEM(addr)) & ~(iMask << 16)) |
  247. ((trans_type & 0xFF) << 24) | ((master & 0xFF) << 16);
  248. } else {
  249. addr = (counter_num <= 3) ? (unsigned long) EMI_MSEL :
  250. ((unsigned long) EMI_MSEL2 + (counter_num / 2 - 2) * 8);
  251. /* clear master and transaction type fields */
  252. value =
  253. readl(IOMEM(addr)) & ~(iMask << ((counter_num % 2) * 16));
  254. /* set master and transaction type fields */
  255. value |= (((trans_type & 0xFF) << 8) |
  256. (master & 0xFF)) << ((counter_num % 2) * 16);
  257. }
  258. mt_reg_sync_writel(value, addr);
  259. return BM_REQ_OK;
  260. }
  261. int BM_SetMaster(const unsigned int counter_num, const unsigned int master)
  262. {
  263. unsigned int value;
  264. unsigned long addr;
  265. const unsigned int iMask = 0xFF;
  266. if (counter_num < 1 || counter_num > BM_COUNTER_MAX)
  267. return BM_ERR_WRONG_REQ;
  268. if (counter_num == 1) {
  269. addr = (unsigned long) EMI_BMEN;
  270. value = (readl(IOMEM(addr)) & ~(iMask << 16)) |
  271. ((master & iMask) << 16);
  272. } else {
  273. addr = (counter_num <= 3) ? (unsigned long) EMI_MSEL :
  274. ((unsigned long) EMI_MSEL2 + (counter_num / 2 - 2) * 8);
  275. /* clear master and transaction type fields */
  276. value =
  277. readl(IOMEM(addr)) & ~(iMask << ((counter_num % 2) * 16));
  278. /* set master and transaction type fields */
  279. value |= ((master & iMask) << ((counter_num % 2) * 16));
  280. }
  281. mt_reg_sync_writel(value, addr);
  282. return BM_REQ_OK;
  283. }
  284. int BM_SetIDSelect(const unsigned int counter_num,
  285. const unsigned int id, const unsigned int enable)
  286. {
  287. unsigned int value, shift_num;
  288. unsigned long addr;
  289. if ((counter_num < 1 || counter_num > BM_COUNTER_MAX)
  290. || (id > 0x1FFF) || (enable > 1))
  291. return BM_ERR_WRONG_REQ;
  292. addr = (unsigned long) EMI_BMID0 + ((counter_num - 1) / 2) * 4;
  293. /* field's offset in the target EMI_BMIDx register */
  294. shift_num = ((counter_num - 1) % 2) * 16;
  295. /* clear SELx_ID field */
  296. value = readl(IOMEM(addr)) & ~(0x1FFF << shift_num);
  297. /* set SELx_ID field */
  298. value |= id << shift_num;
  299. mt_reg_sync_writel(value, addr);
  300. value = (readl(IOMEM(EMI_BMEN2)) & ~(1 << (counter_num - 1))) |
  301. (enable << (counter_num - 1));
  302. mt_reg_sync_writel(value, EMI_BMEN2);
  303. return BM_REQ_OK;
  304. }
  305. int BM_SetUltraHighFilter(const unsigned int counter_num,
  306. const unsigned int enable)
  307. {
  308. unsigned int value;
  309. if ((counter_num < 1 || counter_num > BM_COUNTER_MAX)
  310. || (enable > 1)) {
  311. return BM_ERR_WRONG_REQ;
  312. }
  313. value = (readl(IOMEM(EMI_BMEN1)) & ~(1 << (counter_num - 1))) |
  314. (enable << (counter_num - 1));
  315. mt_reg_sync_writel(value, EMI_BMEN1);
  316. return BM_REQ_OK;
  317. }
  318. int BM_SetLatencyCounter(void)
  319. {
  320. unsigned int value;
  321. value = readl(IOMEM(EMI_BMEN2)) & ~(0x3 << 24);
  322. /*emi_ttype1 -- emi_ttype7 change as total latencies for m0 -- m6,
  323. and emi_ttype9 -- emi_ttype15 change
  324. as total transaction counts for m0 -- m6 */
  325. value |= (0x2 << 24);
  326. mt_reg_sync_writel(value, EMI_BMEN2);
  327. return BM_REQ_OK;
  328. }
  329. int BM_GetLatencyCycle(const unsigned int counter_num)
  330. {
  331. unsigned int cycle_count;
  332. switch (counter_num) {
  333. case 1:
  334. cycle_count = readl(IOMEM(EMI_TTYPE1));
  335. break;
  336. case 2:
  337. cycle_count = readl(IOMEM(EMI_TTYPE2));
  338. break;
  339. case 3:
  340. cycle_count = readl(IOMEM(EMI_TTYPE3));
  341. break;
  342. case 4:
  343. cycle_count = readl(IOMEM(EMI_TTYPE4));
  344. break;
  345. case 5:
  346. cycle_count = readl(IOMEM(EMI_TTYPE5));
  347. break;
  348. case 6:
  349. cycle_count = readl(IOMEM(EMI_TTYPE6));
  350. break;
  351. case 7:
  352. cycle_count = readl(IOMEM(EMI_TTYPE7));
  353. break;
  354. case 9:
  355. cycle_count = readl(IOMEM(EMI_TTYPE9));
  356. break;
  357. case 10:
  358. cycle_count = readl(IOMEM(EMI_TTYPE10));
  359. break;
  360. case 11:
  361. cycle_count = readl(IOMEM(EMI_TTYPE11));
  362. break;
  363. case 12:
  364. cycle_count = readl(IOMEM(EMI_TTYPE12));
  365. break;
  366. case 13:
  367. cycle_count = readl(IOMEM(EMI_TTYPE13));
  368. break;
  369. case 14:
  370. cycle_count = readl(IOMEM(EMI_TTYPE14));
  371. break;
  372. case 15:
  373. cycle_count = readl(IOMEM(EMI_TTYPE15));
  374. break;
  375. case 16:
  376. cycle_count = readl(IOMEM(EMI_TTYPE16));
  377. break;
  378. #if defined(CONFIG_ARCH_MT6755) || defined(CONFIG_ARCH_MT6797)
  379. case 17:
  380. cycle_count = readl(IOMEM(EMI_TTYPE17));
  381. break;
  382. case 18:
  383. cycle_count = readl(IOMEM(EMI_TTYPE18));
  384. break;
  385. case 19:
  386. cycle_count = readl(IOMEM(EMI_TTYPE19));
  387. break;
  388. case 20:
  389. cycle_count = readl(IOMEM(EMI_TTYPE20));
  390. break;
  391. case 21:
  392. cycle_count = readl(IOMEM(EMI_TTYPE21));
  393. break;
  394. #endif
  395. default:
  396. return BM_ERR_WRONG_REQ;
  397. }
  398. return cycle_count;
  399. }
  400. int BM_GetEmiDcm(void)
  401. {
  402. /* return ((readl(IOMEM(EMI_CONM)) >> 24) ? 1 : 0); */
  403. return readl(IOMEM(EMI_CONM)) >> 24;
  404. }
  405. int BM_SetEmiDcm(const unsigned int setting)
  406. {
  407. unsigned int value;
  408. value = readl(IOMEM(EMI_CONM));
  409. mt_reg_sync_writel((value & 0x00FFFFFF) | (setting << 24), EMI_CONM);
  410. return BM_REQ_OK;
  411. }
  412. unsigned int DRAMC_GetPageHitCount(const unsigned int CountType)
  413. {
  414. unsigned int iCount;
  415. switch (CountType) {
  416. case DRAMC_R2R:
  417. iCount = ucDram_Register_Read(DRAMC_R2R_PAGE_HIT);
  418. break;
  419. case DRAMC_R2W:
  420. iCount = ucDram_Register_Read(DRAMC_R2W_PAGE_HIT);
  421. break;
  422. case DRAMC_W2R:
  423. iCount = ucDram_Register_Read(DRAMC_W2R_PAGE_HIT);
  424. break;
  425. case DRAMC_W2W:
  426. iCount = ucDram_Register_Read(DRAMC_W2W_PAGE_HIT);
  427. break;
  428. case DRAMC_ALL:
  429. iCount = ucDram_Register_Read(DRAMC_R2R_PAGE_HIT) +
  430. ucDram_Register_Read(DRAMC_R2W_PAGE_HIT) +
  431. ucDram_Register_Read(DRAMC_W2R_PAGE_HIT) +
  432. ucDram_Register_Read(DRAMC_W2W_PAGE_HIT);
  433. break;
  434. default:
  435. return BM_ERR_WRONG_REQ;
  436. }
  437. return iCount;
  438. }
  439. unsigned int DRAMC_GetPageMissCount(const unsigned int CountType)
  440. {
  441. unsigned int iCount;
  442. switch (CountType) {
  443. case DRAMC_R2R:
  444. iCount = ucDram_Register_Read(DRAMC_R2R_PAGE_MISS);
  445. break;
  446. case DRAMC_R2W:
  447. iCount = ucDram_Register_Read(DRAMC_R2W_PAGE_MISS);
  448. break;
  449. case DRAMC_W2R:
  450. iCount = ucDram_Register_Read(DRAMC_W2R_PAGE_MISS);
  451. break;
  452. case DRAMC_W2W:
  453. iCount = ucDram_Register_Read(DRAMC_W2W_PAGE_MISS);
  454. break;
  455. case DRAMC_ALL:
  456. iCount = ucDram_Register_Read(DRAMC_R2R_PAGE_MISS) +
  457. ucDram_Register_Read(DRAMC_R2W_PAGE_MISS) +
  458. ucDram_Register_Read(DRAMC_W2R_PAGE_MISS) +
  459. ucDram_Register_Read(DRAMC_W2W_PAGE_MISS);
  460. break;
  461. default:
  462. return BM_ERR_WRONG_REQ;
  463. }
  464. return iCount;
  465. }
  466. unsigned int DRAMC_GetInterbankCount(const unsigned int CountType)
  467. {
  468. unsigned int iCount;
  469. switch (CountType) {
  470. case DRAMC_R2R:
  471. iCount = ucDram_Register_Read(DRAMC_R2R_INTERBANK);
  472. break;
  473. case DRAMC_R2W:
  474. iCount = ucDram_Register_Read(DRAMC_R2W_INTERBANK);
  475. break;
  476. case DRAMC_W2R:
  477. iCount = ucDram_Register_Read(DRAMC_W2R_INTERBANK);
  478. break;
  479. case DRAMC_W2W:
  480. iCount = ucDram_Register_Read(DRAMC_W2W_INTERBANK);
  481. break;
  482. case DRAMC_ALL:
  483. iCount = ucDram_Register_Read(DRAMC_R2R_INTERBANK) +
  484. ucDram_Register_Read(DRAMC_R2W_INTERBANK) +
  485. ucDram_Register_Read(DRAMC_W2R_INTERBANK) +
  486. ucDram_Register_Read(DRAMC_W2W_INTERBANK);
  487. break;
  488. default:
  489. return BM_ERR_WRONG_REQ;
  490. }
  491. return iCount;
  492. }
  493. unsigned int DRAMC_GetIdleCount(void)
  494. {
  495. return ucDram_Register_Read(DRAMC_IDLE_COUNT);
  496. }
  497. #if defined(CONFIG_ARCH_MT6755) || defined(CONFIG_ARCH_MT6797)
  498. unsigned int BM_GetBWST(void)
  499. {
  500. return readl(IOMEM(EMI_BWST));
  501. }
  502. unsigned int BM_GetBWST1(void)
  503. {
  504. return readl(IOMEM(EMI_BWST1));
  505. }
  506. int BM_SetBW(const unsigned int BW_config)
  507. {
  508. unsigned int value;
  509. value = readl(IOMEM(EMI_CONH));
  510. value &= 0xFFFF8007;
  511. value |= BW_config & 0x7FF8;
  512. mt_reg_sync_writel(value, EMI_CONH);
  513. return BM_REQ_OK;
  514. }
  515. int BM_SetBW1(const unsigned int BW_config)
  516. {
  517. unsigned int value;
  518. value = readl(IOMEM(EMI_CONO));
  519. value &= 0xFF008007;
  520. value |= BW_config & 0xFF7FF8;
  521. mt_reg_sync_writel(value, EMI_CONO);
  522. return BM_REQ_OK;
  523. }
  524. unsigned int BM_GetBW(void)
  525. {
  526. return readl(IOMEM(EMI_CONH)) & 0x7FF8;
  527. }
  528. unsigned int BM_GetBW1(void)
  529. {
  530. return readl(IOMEM(EMI_CONO)) & 0xFF7FF8;
  531. }
  532. #endif
  533. void *mt_emi_base_get(void)
  534. {
  535. return EMI_BASE_ADDR;
  536. }
  537. EXPORT_SYMBOL(mt_emi_base_get);