mt_mem_bw.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include <linux/device.h>
  2. #include <linux/module.h>
  3. #include <linux/uaccess.h>
  4. #include <linux/delay.h>
  5. #include <linux/platform_device.h>
  6. #include <linux/sched.h>
  7. #include "mach/mt_emi_bm.h"
  8. #include "mach/mt_mem_bw.h"
  9. #include <asm/div64.h>
  10. unsigned long long last_time_ns;
  11. long long LastWordAllCount = 0;
  12. /***********************************************
  13. * register / unregister g_pGetMemBW CB
  14. ***********************************************/
  15. static getmembw_func g_pGetMemBW; /* not initialise statics to 0 or NULL */
  16. void mt_getmembw_registerCB(getmembw_func pCB)
  17. {
  18. if (pCB == NULL) {
  19. /* reset last time & word all count */
  20. last_time_ns = sched_clock();
  21. LastWordAllCount = 0;
  22. pr_err("[get_mem_bw] register CB is a null function\n");
  23. } else {
  24. pr_err("[get_mem_bw] register CB successful\n");
  25. }
  26. g_pGetMemBW = pCB;
  27. }
  28. EXPORT_SYMBOL(mt_getmembw_registerCB);
  29. unsigned long long get_mem_bw(void)
  30. {
  31. unsigned long long throughput;
  32. long long WordAllCount;
  33. unsigned long long current_time_ns, time_period_ns;
  34. int count;
  35. long long value;
  36. int emi_dcm_disable;
  37. #if DISABLE_FLIPPER_FUNC
  38. return 0;
  39. #endif
  40. if (g_pGetMemBW)
  41. return g_pGetMemBW();
  42. emi_dcm_disable = BM_GetEmiDcm();
  43. /* pr_err("[get_mem_bw]emi_dcm_disable = %d\n", emi_dcm_disable); */
  44. current_time_ns = sched_clock();
  45. time_period_ns = current_time_ns - last_time_ns;
  46. /* pr_err("[get_mem_bw]last_time=%llu, current_time=%llu,
  47. period=%llu\n", last_time_ns, current_time_ns, time_period_ns); */
  48. /* disable_infra_dcm(); */
  49. BM_SetEmiDcm(0xff); /* disable EMI dcm */
  50. BM_Pause();
  51. WordAllCount = BM_GetWordAllCount();
  52. if (WordAllCount == 0) {
  53. LastWordAllCount = 0;
  54. } else if (WordAllCount == BM_ERR_OVERRUN) {
  55. pr_debug("[get_mem_bw] BM_ERR_OVERRUN\n");
  56. WordAllCount = 0;
  57. LastWordAllCount = 0;
  58. BM_Enable(0); /* stop EMI monitors will reset all counters */
  59. BM_Enable(1); /* start EMI monitor counting */
  60. }
  61. WordAllCount -= LastWordAllCount;
  62. throughput = (WordAllCount * 8 * 1000);
  63. if (time_period_ns >= 0xFFFFFFFF) { /* uint32_t overflow */
  64. do_div(time_period_ns, 10000000);
  65. do_div(throughput, 10000000);
  66. pr_debug("[get_mem_bw] time_period_ns overflow lst\n");
  67. /* pr_err("[get_mem_bw] time_period_ns overflow 1st\n"); */
  68. if (time_period_ns >= 0xFFFFFFFF) { /* uint32_t overflow */
  69. do_div(time_period_ns, 1000);
  70. do_div(throughput, 1000);
  71. pr_debug("[get_mem_bw] time_period_ns overflow 2nd\n");
  72. /* pr_err("[get_mem_bw] time_period overflow 2nd\n"); */
  73. }
  74. }
  75. do_div(throughput, time_period_ns);
  76. /* pr_err("[get_mem_bw]Total MEMORY THROUGHPUT =%llu(MB/s),
  77. WordAllCount_delta = 0x%llx, LastWordAllCount = 0x%llx\n",
  78. throughput, WordAllCount, LastWordAllCount); */
  79. /* stopping EMI monitors will reset all counters */
  80. BM_Enable(0);
  81. value = BM_GetWordAllCount();
  82. count = 100;
  83. if ((value != 0) && (value > 0xB0000000)) {
  84. do {
  85. value = BM_GetWordAllCount();
  86. if (value != 0) {
  87. count--;
  88. BM_Enable(1);
  89. BM_Enable(0);
  90. } else
  91. break;
  92. } while (count > 0);
  93. }
  94. LastWordAllCount = value;
  95. /*pr_err("[get_mem_bw]loop count = %d,
  96. last_word_all_count = 0x%llx\n", count, LastWordAllCount); */
  97. /* start EMI monitor counting */
  98. BM_Enable(1);
  99. last_time_ns = sched_clock();
  100. /* restore_infra_dcm();*/
  101. BM_SetEmiDcm(emi_dcm_disable);
  102. /*pr_err("[get_mem_bw]throughput = %llx\n", throughput);*/
  103. return throughput;
  104. }
  105. static int mem_bw_suspend_callback(struct device *dev)
  106. {
  107. /*pr_err("[get_mem_bw]mem_bw_suspend_callback\n");*/
  108. LastWordAllCount = 0;
  109. BM_Pause();
  110. return 0;
  111. }
  112. static int mem_bw_resume_callback(struct device *dev)
  113. {
  114. /* pr_err("[get_mem_bw]mem_bw_resume_callback\n"); */
  115. BM_Continue();
  116. return 0;
  117. }
  118. const struct dev_pm_ops mt_mem_bw_pm_ops = {
  119. .suspend = mem_bw_suspend_callback,
  120. .resume = mem_bw_resume_callback,
  121. .restore_early = NULL,
  122. };
  123. struct platform_device mt_mem_bw_pdev = {
  124. .name = "mt-mem_bw",
  125. .id = -1,
  126. };
  127. static struct platform_driver mt_mem_bw_pdrv = {
  128. .probe = NULL,
  129. .remove = NULL,
  130. .driver = {
  131. .name = "mt-mem_bw",
  132. .pm = &mt_mem_bw_pm_ops,
  133. .owner = THIS_MODULE,
  134. },
  135. };
  136. static int __init mon_kernel_init(void)
  137. {
  138. int ret = 0;
  139. int emi_dcm_disable;
  140. BM_Init();
  141. /* disable_infra_dcm(); */
  142. emi_dcm_disable = BM_GetEmiDcm();
  143. /* pr_err("[MT_MEM_BW]emi_dcm_disable = %d\n", emi_dcm_disable); */
  144. BM_SetEmiDcm(0xff); /* disable EMI dcm */
  145. BM_SetReadWriteType(BM_BOTH_READ_WRITE);
  146. BM_SetMonitorCounter(1, BM_MASTER_MM1 | BM_MASTER_MM1,
  147. BM_TRANS_TYPE_4BEAT | BM_TRANS_TYPE_8Byte | BM_TRANS_TYPE_BURST_WRAP);
  148. BM_SetMonitorCounter(2, BM_MASTER_AP_MCU1 | BM_MASTER_AP_MCU2,
  149. BM_TRANS_TYPE_4BEAT | BM_TRANS_TYPE_8Byte | BM_TRANS_TYPE_BURST_WRAP);
  150. BM_SetMonitorCounter(3, BM_MASTER_MD_MCU | BM_MASTER_2G_3G_MDDMA,
  151. BM_TRANS_TYPE_4BEAT | BM_TRANS_TYPE_8Byte | BM_TRANS_TYPE_BURST_WRAP);
  152. BM_SetMonitorCounter(4, BM_MASTER_GPU1 | BM_MASTER_GPU1,
  153. BM_TRANS_TYPE_4BEAT | BM_TRANS_TYPE_8Byte | BM_TRANS_TYPE_BURST_WRAP);
  154. BM_SetLatencyCounter();
  155. /* stopping EMI monitors will reset all counters */
  156. BM_Enable(0);
  157. /* start EMI monitor counting */
  158. BM_Enable(1);
  159. last_time_ns = sched_clock();
  160. /* restore_infra_dcm(); */
  161. BM_SetEmiDcm(emi_dcm_disable); /* enable EMI dcm */
  162. /* register platform device/driver */
  163. ret = platform_device_register(&mt_mem_bw_pdev);
  164. if (ret) {
  165. pr_err("fail to register mem_bw device @ %s()\n", __func__);
  166. goto out;
  167. }
  168. ret = platform_driver_register(&mt_mem_bw_pdrv);
  169. if (ret) {
  170. pr_err("fail to register mem_bw driver @ %s()\n", __func__);
  171. platform_device_unregister(&mt_mem_bw_pdev);
  172. }
  173. out:
  174. return ret;
  175. }
  176. static void __exit mon_kernel_exit(void)
  177. {
  178. }
  179. module_init(mon_kernel_init);
  180. module_exit(mon_kernel_exit);