emi_bwl.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. #include <linux/kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/interrupt.h>
  4. #include <linux/semaphore.h>
  5. #include <linux/device.h>
  6. #include <linux/platform_device.h>
  7. #include <linux/of.h>
  8. #include <linux/of_address.h>
  9. #include <linux/of_irq.h>
  10. #include <linux/printk.h>
  11. #define MET_USER_EVENT_SUPPORT
  12. /* #include <linux/met_drv.h> */
  13. #include <mt-plat/mt_io.h>
  14. #include <mt-plat/sync_write.h>
  15. #include "mach/emi_bwl.h"
  16. DEFINE_SEMAPHORE(emi_bwl_sem);
  17. void __iomem *EMI_BASE_ADDR = NULL;
  18. static struct platform_driver mem_bw_ctrl = {
  19. .driver = {
  20. .name = "mem_bw_ctrl",
  21. .owner = THIS_MODULE,
  22. },
  23. };
  24. static struct platform_driver ddr_type = {
  25. .driver = {
  26. .name = "ddr_type",
  27. .owner = THIS_MODULE,
  28. },
  29. };
  30. /* define EMI bandwiwth limiter control table */
  31. static struct emi_bwl_ctrl ctrl_tbl[NR_CON_SCE];
  32. /* current concurrency scenario */
  33. static int cur_con_sce = 0x0FFFFFFF;
  34. #if defined(CONFIG_ARCH_MT6735) && !defined(CONFIG_MTK_EMI_D1P)
  35. /* define concurrency scenario strings */
  36. static const char const *con_sce_str[] = {
  37. #define X_CON_SCE(con_sce, arba, arbb, arbc, \
  38. arbd, arbe, arbf, arbg2) (#con_sce),
  39. #include "mach/con_sce_lpddr3_1600_D1.h"
  40. #undef X_CON_SCE
  41. };
  42. /****************** For LPDDR2-1066******************/
  43. static const unsigned int emi_arba_lpddr2_1066_val[] = {
  44. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arba,
  45. #include "mach/con_sce_lpddr2_1066_D1.h"
  46. #undef X_CON_SCE
  47. };
  48. static const unsigned int emi_arbb_lpddr2_1066_val[] = {
  49. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbb,
  50. #include "mach/con_sce_lpddr2_1066_D1.h"
  51. #undef X_CON_SCE
  52. };
  53. static const unsigned int emi_arbc_lpddr2_1066_val[] = {
  54. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbc,
  55. #include "mach/con_sce_lpddr2_1066_D1.h"
  56. #undef X_CON_SCE
  57. };
  58. static const unsigned int emi_arbd_lpddr2_1066_val[] = {
  59. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbd,
  60. #include "mach/con_sce_lpddr2_1066_D1.h"
  61. #undef X_CON_SCE
  62. };
  63. static const unsigned int emi_arbe_lpddr2_1066_val[] = {
  64. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbe,
  65. #include "mach/con_sce_lpddr2_1066_D1.h"
  66. #undef X_CON_SCE
  67. };
  68. static const unsigned int emi_arbf_lpddr2_1066_val[] = {
  69. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbf,
  70. #include "mach/con_sce_lpddr2_1066_D1.h"
  71. #undef X_CON_SCE
  72. };
  73. static const unsigned int emi_arbg2_lpddr2_1066_val[] = {
  74. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbg2,
  75. #include "mach/con_sce_lpddr2_1066_D1.h"
  76. #undef X_CON_SCE
  77. };
  78. /****************** For LPDDR3-1600******************/
  79. static const unsigned int emi_arba_lpddr3_1600_val[] = {
  80. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arba,
  81. #include "mach/con_sce_lpddr3_1600_D1.h"
  82. #undef X_CON_SCE
  83. };
  84. static const unsigned int emi_arbb_lpddr3_1600_val[] = {
  85. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbb,
  86. #include "mach/con_sce_lpddr3_1600_D1.h"
  87. #undef X_CON_SCE
  88. };
  89. static const unsigned int emi_arbc_lpddr3_1600_val[] = {
  90. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbc,
  91. #include "mach/con_sce_lpddr3_1600_D1.h"
  92. #undef X_CON_SCE
  93. };
  94. static const unsigned int emi_arbd_lpddr3_1600_val[] = {
  95. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbd,
  96. #include "mach/con_sce_lpddr3_1600_D1.h"
  97. #undef X_CON_SCE
  98. };
  99. static const unsigned int emi_arbe_lpddr3_1600_val[] = {
  100. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbe,
  101. #include "mach/con_sce_lpddr3_1600_D1.h"
  102. #undef X_CON_SCE
  103. };
  104. static const unsigned int emi_arbf_lpddr3_1600_val[] = {
  105. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbf,
  106. #include "mach/con_sce_lpddr3_1600_D1.h"
  107. #undef X_CON_SCE
  108. };
  109. static const unsigned int emi_arbg2_lpddr3_1600_val[] = {
  110. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbg2,
  111. #include "mach/con_sce_lpddr3_1600_D1.h"
  112. #undef X_CON_SCE
  113. };
  114. #elif defined(CONFIG_ARCH_MT6735M)
  115. /* define concurrency scenario strings */
  116. static const char const *con_sce_str[] = {
  117. #define X_CON_SCE(con_sce, arba, arbb, arbc, \
  118. arbd, arbe, arbf, arbg2) (#con_sce),
  119. #include "mach/con_sce_lpddr3_1600_D2.h"
  120. #undef X_CON_SCE
  121. };
  122. /****************** For LPDDR2-1066******************/
  123. static const unsigned int emi_arba_lpddr2_1066_val[] = {
  124. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arba,
  125. #include "mach/con_sce_lpddr2_1066_D2.h"
  126. #undef X_CON_SCE
  127. };
  128. static const unsigned int emi_arbb_lpddr2_1066_val[] = {
  129. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbb,
  130. #include "mach/con_sce_lpddr2_1066_D2.h"
  131. #undef X_CON_SCE
  132. };
  133. static const unsigned int emi_arbc_lpddr2_1066_val[] = {
  134. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbc,
  135. #include "mach/con_sce_lpddr2_1066_D2.h"
  136. #undef X_CON_SCE
  137. };
  138. static const unsigned int emi_arbd_lpddr2_1066_val[] = {
  139. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbd,
  140. #include "mach/con_sce_lpddr2_1066_D2.h"
  141. #undef X_CON_SCE
  142. };
  143. static const unsigned int emi_arbe_lpddr2_1066_val[] = {
  144. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbe,
  145. #include "mach/con_sce_lpddr2_1066_D2.h"
  146. #undef X_CON_SCE
  147. };
  148. static const unsigned int emi_arbf_lpddr2_1066_val[] = {
  149. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbf,
  150. #include "mach/con_sce_lpddr2_1066_D2.h"
  151. #undef X_CON_SCE
  152. };
  153. static const unsigned int emi_arbg2_lpddr2_1066_val[] = {
  154. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbg2,
  155. #include "mach/con_sce_lpddr2_1066_D2.h"
  156. #undef X_CON_SCE
  157. };
  158. /****************** For LPDDR3-1600******************/
  159. static const unsigned int emi_arba_lpddr3_1600_val[] = {
  160. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arba,
  161. #include "mach/con_sce_lpddr3_1600_D2.h"
  162. #undef X_CON_SCE
  163. };
  164. static const unsigned int emi_arbb_lpddr3_1600_val[] = {
  165. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbb,
  166. #include "mach/con_sce_lpddr3_1600_D2.h"
  167. #undef X_CON_SCE
  168. };
  169. static const unsigned int emi_arbc_lpddr3_1600_val[] = {
  170. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbc,
  171. #include "mach/con_sce_lpddr3_1600_D2.h"
  172. #undef X_CON_SCE
  173. };
  174. static const unsigned int emi_arbd_lpddr3_1600_val[] = {
  175. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbd,
  176. #include "mach/con_sce_lpddr3_1600_D2.h"
  177. #undef X_CON_SCE
  178. };
  179. static const unsigned int emi_arbe_lpddr3_1600_val[] = {
  180. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbe,
  181. #include "mach/con_sce_lpddr3_1600_D2.h"
  182. #undef X_CON_SCE
  183. };
  184. static const unsigned int emi_arbf_lpddr3_1600_val[] = {
  185. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbf,
  186. #include "mach/con_sce_lpddr3_1600_D2.h"
  187. #undef X_CON_SCE
  188. };
  189. static const unsigned int emi_arbg2_lpddr3_1600_val[] = {
  190. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbg2,
  191. #include "mach/con_sce_lpddr3_1600_D2.h"
  192. #undef X_CON_SCE
  193. };
  194. #elif defined(CONFIG_ARCH_MT6753) || defined(CONFIG_MTK_EMI_D1P)
  195. /* define concurrency scenario strings */
  196. static const char const *con_sce_str[] = {
  197. #define X_CON_SCE(con_sce, arba, arbb, arbc, \
  198. arbd, arbe, arbf, arbg2) (#con_sce),
  199. #include "mach/con_sce_lpddr3_1600_D3.h"
  200. #undef X_CON_SCE
  201. };
  202. /****************** For LPDDR2-1066******************/
  203. static const unsigned int emi_arba_lpddr2_1066_val[] = {
  204. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arba,
  205. #include "mach/con_sce_lpddr2_1066_D3.h"
  206. #undef X_CON_SCE
  207. };
  208. static const unsigned int emi_arbb_lpddr2_1066_val[] = {
  209. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbb,
  210. #include "mach/con_sce_lpddr2_1066_D3.h"
  211. #undef X_CON_SCE
  212. };
  213. static const unsigned int emi_arbc_lpddr2_1066_val[] = {
  214. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbc,
  215. #include "mach/con_sce_lpddr2_1066_D3.h"
  216. #undef X_CON_SCE
  217. };
  218. static const unsigned int emi_arbd_lpddr2_1066_val[] = {
  219. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbd,
  220. #include "mach/con_sce_lpddr2_1066_D3.h"
  221. #undef X_CON_SCE
  222. };
  223. static const unsigned int emi_arbe_lpddr2_1066_val[] = {
  224. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbe,
  225. #include "mach/con_sce_lpddr2_1066_D3.h"
  226. #undef X_CON_SCE
  227. };
  228. static const unsigned int emi_arbf_lpddr2_1066_val[] = {
  229. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbf,
  230. #include "mach/con_sce_lpddr2_1066_D3.h"
  231. #undef X_CON_SCE
  232. };
  233. static const unsigned int emi_arbg2_lpddr2_1066_val[] = {
  234. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbg2,
  235. #include "mach/con_sce_lpddr2_1066_D3.h"
  236. #undef X_CON_SCE
  237. };
  238. /****************** For LPDDR3-1600******************/
  239. static const unsigned int emi_arba_lpddr3_1600_val[] = {
  240. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arba,
  241. #include "mach/con_sce_lpddr3_1600_D3.h"
  242. #undef X_CON_SCE
  243. };
  244. static const unsigned int emi_arbb_lpddr3_1600_val[] = {
  245. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbb,
  246. #include "mach/con_sce_lpddr3_1600_D3.h"
  247. #undef X_CON_SCE
  248. };
  249. static const unsigned int emi_arbc_lpddr3_1600_val[] = {
  250. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbc,
  251. #include "mach/con_sce_lpddr3_1600_D3.h"
  252. #undef X_CON_SCE
  253. };
  254. static const unsigned int emi_arbd_lpddr3_1600_val[] = {
  255. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbd,
  256. #include "mach/con_sce_lpddr3_1600_D3.h"
  257. #undef X_CON_SCE
  258. };
  259. static const unsigned int emi_arbe_lpddr3_1600_val[] = {
  260. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbe,
  261. #include "mach/con_sce_lpddr3_1600_D3.h"
  262. #undef X_CON_SCE
  263. };
  264. static const unsigned int emi_arbf_lpddr3_1600_val[] = {
  265. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbf,
  266. #include "mach/con_sce_lpddr3_1600_D3.h"
  267. #undef X_CON_SCE
  268. };
  269. static const unsigned int emi_arbg2_lpddr3_1600_val[] = {
  270. #define X_CON_SCE(con_sce, arba, arbb, arbc, arbd, arbe, arbf, arbg2) arbg2,
  271. #include "mach/con_sce_lpddr3_1600_D3.h"
  272. #undef X_CON_SCE
  273. };
  274. #endif
  275. int get_dram_type(void)
  276. {
  277. unsigned int value = ucDram_Register_Read(DRAMC_ACTIM1);
  278. if ((value >> 28) & 0x1)
  279. return LPDDR3_1600;
  280. else
  281. return LPDDR2_1066;
  282. }
  283. /*
  284. * mtk_mem_bw_ctrl: set EMI bandwidth limiter for memory bandwidth control
  285. * @sce: concurrency scenario ID
  286. * @op: either ENABLE_CON_SCE or DISABLE_CON_SCE
  287. * Return 0 for success; return negative values for failure.
  288. */
  289. int mtk_mem_bw_ctrl(int sce, int op)
  290. {
  291. int i, highest;
  292. if (sce >= NR_CON_SCE)
  293. return -1;
  294. if (op != ENABLE_CON_SCE && op != DISABLE_CON_SCE)
  295. return -1;
  296. if (in_interrupt())
  297. return -1;
  298. down(&emi_bwl_sem);
  299. if (op == ENABLE_CON_SCE)
  300. ctrl_tbl[sce].ref_cnt++;
  301. else if (op == DISABLE_CON_SCE) {
  302. if (ctrl_tbl[sce].ref_cnt != 0)
  303. ctrl_tbl[sce].ref_cnt--;
  304. }
  305. /* find the scenario with the highest priority */
  306. highest = -1;
  307. for (i = 0; i < NR_CON_SCE; i++) {
  308. if (ctrl_tbl[i].ref_cnt != 0) {
  309. highest = i;
  310. break;
  311. }
  312. }
  313. if (highest == -1)
  314. highest = CON_SCE_NORMAL;
  315. /* set new EMI bandwidth limiter value */
  316. if (highest != cur_con_sce) {
  317. if (get_dram_type() == LPDDR3_1600) {
  318. writel(emi_arba_lpddr3_1600_val[highest], EMI_ARBA);
  319. writel(emi_arbb_lpddr3_1600_val[highest], EMI_ARBB);
  320. writel(emi_arbc_lpddr3_1600_val[highest], EMI_ARBC);
  321. writel(emi_arbd_lpddr3_1600_val[highest], EMI_ARBD);
  322. writel(emi_arbe_lpddr3_1600_val[highest], EMI_ARBE);
  323. writel(emi_arbf_lpddr3_1600_val[highest], EMI_ARBF);
  324. mt_reg_sync_writel(emi_arbg2_lpddr3_1600_val[highest],
  325. EMI_ARBG_2ND);
  326. } else if (get_dram_type() == LPDDR2_1066) {
  327. writel(emi_arba_lpddr2_1066_val[highest], EMI_ARBA);
  328. writel(emi_arbb_lpddr2_1066_val[highest], EMI_ARBB);
  329. writel(emi_arbc_lpddr2_1066_val[highest], EMI_ARBC);
  330. writel(emi_arbd_lpddr2_1066_val[highest], EMI_ARBD);
  331. writel(emi_arbe_lpddr2_1066_val[highest], EMI_ARBE);
  332. writel(emi_arbf_lpddr2_1066_val[highest], EMI_ARBF);
  333. mt_reg_sync_writel(emi_arbg2_lpddr2_1066_val[highest],
  334. EMI_ARBG_2ND);
  335. }
  336. cur_con_sce = highest;
  337. }
  338. up(&emi_bwl_sem);
  339. /* met_show_bw_limiter(); */
  340. return 0;
  341. }
  342. /*
  343. * ddr_type_show: sysfs ddr_type file show function.
  344. * @driver:
  345. * @buf: the string of ddr type
  346. * Return the number of read bytes.
  347. */
  348. static ssize_t ddr_type_show(struct device_driver *driver, char *buf)
  349. {
  350. if (get_dram_type() == LPDDR3_1600)
  351. sprintf(buf, "LPDDR3_1600\n");
  352. else if (get_dram_type() == LPDDR2_1066)
  353. sprintf(buf, "LPDDR2_1066\n");
  354. return strlen(buf);
  355. }
  356. /*
  357. * ddr_type_store: sysfs ddr_type file store function.
  358. * @driver:
  359. * @buf:
  360. * @count:
  361. * Return the number of write bytes.
  362. */
  363. static ssize_t ddr_type_store(struct device_driver *driver,
  364. const char *buf, size_t count)
  365. {
  366. /*do nothing */
  367. return count;
  368. }
  369. DRIVER_ATTR(ddr_type, 0644, ddr_type_show, ddr_type_store);
  370. /*
  371. * con_sce_show: sysfs con_sce file show function.
  372. * @driver:
  373. * @buf:
  374. * Return the number of read bytes.
  375. */
  376. static ssize_t con_sce_show(struct device_driver *driver, char *buf)
  377. {
  378. char *ptr = buf;
  379. int i = 0;
  380. if (cur_con_sce >= NR_CON_SCE)
  381. ptr += sprintf(ptr, "none\n");
  382. else
  383. ptr += sprintf(ptr, "current scenario: %s\n",
  384. con_sce_str[cur_con_sce]);
  385. #if 1
  386. ptr += sprintf(ptr, "%s\n", con_sce_str[cur_con_sce]);
  387. ptr += sprintf(ptr, "EMI_ARBA = 0x%x\n", readl(IOMEM(EMI_ARBA)));
  388. ptr += sprintf(ptr, "EMI_ARBB = 0x%x\n", readl(IOMEM(EMI_ARBB)));
  389. ptr += sprintf(ptr, "EMI_ARBC = 0x%x\n", readl(IOMEM(EMI_ARBC)));
  390. ptr += sprintf(ptr, "EMI_ARBD = 0x%x\n", readl(IOMEM(EMI_ARBD)));
  391. ptr += sprintf(ptr, "EMI_ARBE = 0x%x\n", readl(IOMEM(EMI_ARBE)));
  392. ptr += sprintf(ptr, "EMI_ARBF = 0x%x\n", readl(IOMEM(EMI_ARBF)));
  393. ptr += sprintf(ptr, "EMI_ARBG = 0x%x\n", readl(IOMEM(EMI_ARBG_2ND)));
  394. for (i = 0; i < NR_CON_SCE; i++)
  395. ptr += sprintf(ptr, "%s = 0x%x\n", con_sce_str[i],
  396. ctrl_tbl[i].ref_cnt);
  397. pr_debug("[EMI BWL] EMI_ARBA = 0x%x\n", readl(IOMEM(EMI_ARBA)));
  398. pr_debug("[EMI BWL] EMI_ARBB = 0x%x\n", readl(IOMEM(EMI_ARBB)));
  399. pr_debug("[EMI BWL] EMI_ARBC = 0x%x\n", readl(IOMEM(EMI_ARBC)));
  400. pr_debug("[EMI BWL] EMI_ARBD = 0x%x\n", readl(IOMEM(EMI_ARBD)));
  401. pr_debug("[EMI BWL] EMI_ARBE = 0x%x\n", readl(IOMEM(EMI_ARBE)));
  402. pr_debug("[EMI BWL] EMI_ARBF = 0x%x\n", readl(IOMEM(EMI_ARBF)));
  403. pr_debug("[EMI BWL] EMI_ARBG = 0x%x\n", readl(IOMEM(EMI_ARBG_2ND)));
  404. #endif
  405. return strlen(buf);
  406. }
  407. /*
  408. * con_sce_store: sysfs con_sce file store function.
  409. * @driver:
  410. * @buf:
  411. * @count:
  412. * Return the number of write bytes.
  413. */
  414. static ssize_t con_sce_store(struct device_driver *driver,
  415. const char *buf, size_t count)
  416. {
  417. int i;
  418. for (i = 0; i < NR_CON_SCE; i++) {
  419. if (!strncmp(buf, con_sce_str[i], strlen(con_sce_str[i]))) {
  420. if (!strncmp
  421. (buf + strlen(con_sce_str[i]) + 1, EN_CON_SCE_STR,
  422. strlen(EN_CON_SCE_STR))) {
  423. mtk_mem_bw_ctrl(i, ENABLE_CON_SCE);
  424. pr_debug("concurrency scenario %s ON\n",
  425. con_sce_str[i]);
  426. break;
  427. } else if (!strncmp(buf + strlen(con_sce_str[i]) + 1,
  428. DIS_CON_SCE_STR, strlen(DIS_CON_SCE_STR))) {
  429. mtk_mem_bw_ctrl(i, DISABLE_CON_SCE);
  430. pr_debug("concurrency scenario %s OFF\n",
  431. con_sce_str[i]);
  432. break;
  433. }
  434. }
  435. }
  436. return count;
  437. }
  438. DRIVER_ATTR(concurrency_scenario, 0644, con_sce_show, con_sce_store);
  439. /*
  440. * emi_bwl_mod_init: module init function.
  441. */
  442. static int __init emi_bwl_mod_init(void)
  443. {
  444. int ret;
  445. struct device_node *node;
  446. /* DTS version */
  447. if (EMI_BASE_ADDR == NULL) {
  448. node = of_find_compatible_node(NULL, NULL, "mediatek,EMI");
  449. if (node) {
  450. EMI_BASE_ADDR = of_iomap(node, 0);
  451. pr_err("get EMI_BASE_ADDR @ %p\n", EMI_BASE_ADDR);
  452. } else {
  453. pr_err("can't find compatible node\n");
  454. return -1;
  455. }
  456. }
  457. ret = mtk_mem_bw_ctrl(CON_SCE_NORMAL, ENABLE_CON_SCE);
  458. if (ret)
  459. pr_err("[EMI/BWL] fail to set EMI bandwidth limiter\n");
  460. /* Register BW ctrl interface */
  461. ret = platform_driver_register(&mem_bw_ctrl);
  462. if (ret)
  463. pr_err("[EMI/BWL] fail to register EMI_BW_LIMITER driver\n");
  464. ret = driver_create_file(&mem_bw_ctrl.driver,
  465. &driver_attr_concurrency_scenario);
  466. if (ret)
  467. pr_err("[EMI/BWL] fail to create EMI_BW_LIMITER sysfs file\n");
  468. /* Register DRAM type information interface */
  469. ret = platform_driver_register(&ddr_type);
  470. if (ret)
  471. pr_err("[EMI/BWL] fail to register DRAM_TYPE driver\n");
  472. ret = driver_create_file(&ddr_type.driver, &driver_attr_ddr_type);
  473. if (ret)
  474. pr_err("[EMI/BWL] fail to create DRAM_TYPE sysfs file\n");
  475. return 0;
  476. }
  477. /*
  478. * emi_bwl_mod_exit: module exit function.
  479. */
  480. static void __exit emi_bwl_mod_exit(void)
  481. {
  482. }
  483. /* EXPORT_SYMBOL(get_dram_type); */
  484. late_initcall(emi_bwl_mod_init);
  485. module_exit(emi_bwl_mod_exit);