mt_static_power.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. #include <linux/kernel.h>
  2. #include <linux/init.h>
  3. #if defined(__KERNEL__)
  4. #include <linux/export.h>
  5. #include <linux/module.h>
  6. #endif
  7. #ifdef CONFIG_ARCH_MT6735
  8. #include "mt_spower_data.h"
  9. #else
  10. #ifdef CONFIG_ARCH_MT6753
  11. #include "mt_spower_data_d3.h"
  12. #else
  13. #include "mt_spower_data_d2.h"
  14. #endif
  15. #endif
  16. #include "mt_static_power.h"
  17. /*
  18. * macro for log
  19. */
  20. #define SPOWER_LOG_NONE 0
  21. #define SPOWER_LOG_WITH_PRINTK 1
  22. /* #define SPOWER_LOG_PRINT SPOWER_LOG_WITH_PRINTK */
  23. #define SPOWER_LOG_PRINT SPOWER_LOG_NONE
  24. #if (SPOWER_LOG_PRINT == SPOWER_LOG_NONE)
  25. #define SPOWER_INFO(fmt, args...)
  26. #elif (SPOWER_LOG_PRINT == SPOWER_LOG_WITH_PRINTK)
  27. #define SPOWER_INFO(fmt, args...)
  28. #endif
  29. static sptbl_t sptab[MT_SPOWER_MAX];
  30. /*
  31. * this table is generated by scramble function.
  32. */
  33. int devinfo_table[] = {
  34. 3539, 492, 1038, 106, 231, 17, 46, 2179,
  35. 4, 481, 1014, 103, 225, 17, 45, 2129,
  36. 3, 516, 1087, 111, 242, 19, 49, 2282,
  37. 4, 504, 1063, 108, 236, 18, 47, 2230,
  38. 4, 448, 946, 96, 210, 15, 41, 1986,
  39. 2, 438, 924, 93, 205, 14, 40, 1941,
  40. 2, 470, 991, 101, 220, 16, 43, 2080,
  41. 3, 459, 968, 98, 215, 16, 42, 2033,
  42. 3, 594, 1250, 129, 279, 23, 57, 2621,
  43. 6, 580, 1221, 126, 273, 22, 56, 2561,
  44. 6, 622, 1309, 136, 293, 24, 60, 2745,
  45. 7, 608, 1279, 132, 286, 23, 59, 2683,
  46. 6, 541, 1139, 117, 254, 20, 51, 2390,
  47. 5, 528, 1113, 114, 248, 19, 50, 2335,
  48. 4, 566, 1193, 123, 266, 21, 54, 2503,
  49. 5, 553, 1166, 120, 260, 21, 53, 2446,
  50. 5, 338, 715, 70, 157, 9, 29, 1505,
  51. 3153, 330, 699, 69, 153, 9, 28, 1470,
  52. 3081, 354, 750, 74, 165, 10, 31, 1576,
  53. 3302, 346, 732, 72, 161, 10, 30, 1540,
  54. 3227, 307, 652, 63, 142, 8, 26, 1371,
  55. 2875, 300, 637, 62, 139, 7, 25, 1340,
  56. 2809, 322, 683, 67, 149, 8, 27, 1436,
  57. 3011, 315, 667, 65, 146, 8, 26, 1404,
  58. 2942, 408, 862, 86, 191, 13, 37, 1811,
  59. 1, 398, 842, 84, 186, 12, 36, 1769,
  60. 1, 428, 903, 91, 200, 14, 39, 1896,
  61. 2, 418, 882, 89, 195, 13, 38, 1853,
  62. 2, 371, 785, 78, 173, 11, 33, 1651,
  63. 3458, 363, 767, 76, 169, 10, 32, 1613,
  64. 3379, 389, 823, 82, 182, 12, 35, 1729,
  65. 1, 380, 804, 80, 177, 11, 34, 1689,
  66. };
  67. int interpolate(int x1, int x2, int x3, int y1, int y2)
  68. {
  69. /* BUG_ON(x1==x2); */
  70. if (x1 == x2)
  71. return (y1 + y2) / 2;
  72. return (x3 - x1) * (y2 - y1) / (x2 - x1) + y1;
  73. }
  74. int interpolate_2d(sptbl_t *tab, int v1, int v2, int t1, int t2, int voltage, int degree)
  75. {
  76. int c1, c2, p1, p2, p;
  77. if (v1 == v2 && t1 == t2) {
  78. p = mA(tab, v1, t1);
  79. return p;
  80. }
  81. if (v1 == v2) {
  82. c1 = mA(tab, v1, t1);
  83. c2 = mA(tab, v1, t2);
  84. p = interpolate(deg(tab, t1), deg(tab, t2), degree, c1, c2);
  85. return p;
  86. }
  87. if (t1 == t2) {
  88. c1 = mA(tab, v1, t1);
  89. c2 = mA(tab, v2, t1);
  90. p = interpolate(mV(tab, v1), mV(tab, v2), voltage, c1, c2);
  91. return p;
  92. }
  93. if (v1 != v2 && t1 != t2) {
  94. c1 = mA(tab, v1, t1);
  95. c2 = mA(tab, v1, t2);
  96. p1 = interpolate(deg(tab, t1), deg(tab, t2), degree, c1, c2);
  97. c1 = mA(tab, v2, t1);
  98. c2 = mA(tab, v2, t2);
  99. p2 = interpolate(deg(tab, t1), deg(tab, t2), degree, c1, c2);
  100. p = interpolate(mV(tab, v1), mV(tab, v2), voltage, p1, p2);
  101. return p;
  102. }
  103. return 0;
  104. }
  105. /* c1, c2, c3(EFUSE) => make sptab 239, 53, 100 */
  106. void interpolate_table(sptbl_t *spt, int c1, int c2, int c3, sptbl_t *tab1, sptbl_t *tab2)
  107. {
  108. int v, t;
  109. /* avoid divid error, if we have bad raw data table */
  110. if (unlikely(c1 == c2)) {
  111. *spt = *tab1;
  112. SPOWER_INFO("sptab equal to tab1:%d/%d\n", c1, c3);
  113. return;
  114. }
  115. SPOWER_INFO("make sptab %d, %d, %d\n", c1, c2, c3);
  116. for (t = 0; t < tsize(spt); t++) {
  117. for (v = 0; v < vsize(spt); v++) {
  118. int *p = &mA(spt, v, t);
  119. p[0] = interpolate(c1, c2, c3, mA(tab1, v, t), mA(tab2, v, t));
  120. SPOWER_INFO("%d ", p[0]);
  121. }
  122. SPOWER_INFO("\n");
  123. }
  124. SPOWER_INFO("make sptab done!\n");
  125. }
  126. int sptab_lookup(sptbl_t *tab, int voltage, int degree)
  127. {
  128. int x1, x2, y1, y2, i;
  129. int mamper;
  130. /* lookup voltage */
  131. for (i = 0; i < vsize(tab); i++) {
  132. if (voltage <= mV(tab, i))
  133. break;
  134. }
  135. if (unlikely(voltage == mV(tab, i))) {
  136. x1 = x2 = i;
  137. } else if (unlikely(i == vsize(tab))) {
  138. x1 = vsize(tab) - 2;
  139. x2 = vsize(tab) - 1;
  140. } else if (i == 0) {
  141. x1 = 0;
  142. x2 = 1;
  143. } else {
  144. x1 = i - 1;
  145. x2 = i;
  146. }
  147. /* lookup degree */
  148. for (i = 0; i < tsize(tab); i++) {
  149. if (degree <= deg(tab, i))
  150. break;
  151. }
  152. if (unlikely(degree == deg(tab, i))) {
  153. y1 = y2 = i;
  154. } else if (unlikely(i == tsize(tab))) {
  155. y1 = tsize(tab) - 2;
  156. y2 = tsize(tab) - 1;
  157. } else if (i == 0) {
  158. y1 = 0;
  159. y2 = 1;
  160. } else {
  161. y1 = i - 1;
  162. y2 = i;
  163. }
  164. mamper = interpolate_2d(tab, x1, x2, y1, y2, voltage, degree);
  165. return mamper;
  166. }
  167. int mt_spower_make_table(sptbl_t *spt, spower_raw_t *spower_raw, int wat, int voltage, int degree)
  168. {
  169. int i;
  170. int c1, c2, c = -1;
  171. sptbl_t tab[MAX_TABLE_SIZE], *tab1, *tab2, *tspt;
  172. BUG_ON(spower_raw->table_size < 3);
  173. /* structurize the raw data */
  174. spower_tab_construct(&tab, spower_raw);
  175. /* lookup tables which the chip type locates to */
  176. for (i = 0; i < spower_raw->table_size; i++) {
  177. c = sptab_lookup(&tab[i], voltage, degree);
  178. /* table order: ff, tt, ss */
  179. if (wat >= c)
  180. break;
  181. }
  182. /*
  183. * There are only 2 tables are used to interpolate to form SPTAB.
  184. * Thus, sptab takes use of the container which raw data is not used anymore.
  185. */
  186. if (wat == c) {
  187. /* just match */
  188. tab1 = tab2 = &tab[i];
  189. /* pointer duplicate */
  190. tspt = tab1;
  191. SPOWER_INFO("sptab equal to tab:%d/%d\n", wat, c);
  192. } else if (i == spower_raw->table_size) {
  193. /* above all */
  194. #if defined(EXTER_POLATION)
  195. tab1 = &tab[spower_raw->table_size - 2];
  196. tab2 = &tab[spower_raw->table_size - 1];
  197. /* occupy the free container*/
  198. tspt = &tab[spower_raw->table_size - 3];
  199. #else /* #if defined (EXTER_POLATION) */
  200. tspt = tab1 = tab2 = &tab[spower_raw->table_size - 1];
  201. #endif /* #if defined (EXTER_POLATION) */
  202. SPOWER_INFO("sptab max tab:%d/%d\n", wat, c);
  203. } else if (i == 0) {
  204. #if defined(EXTER_POLATION)
  205. /* below all */
  206. tab1 = &tab[0];
  207. tab2 = &tab[1];
  208. /* occupy the free container*/
  209. tspt = &tab[2];
  210. #else /* #if defined (EXTER_POLATION) */
  211. tspt = tab1 = tab2 = &tab[0];
  212. #endif /* #if defined (EXTER_POLATION) */
  213. SPOWER_INFO("sptab min tab:%d/%d\n", wat, c);
  214. } else {
  215. /* anyone */
  216. tab1 = &tab[i - 1];
  217. tab2 = &tab[i];
  218. /* occupy the free container*/
  219. tspt = &tab[(i + 1) % spower_raw->table_size];
  220. SPOWER_INFO("sptab interpolate tab:%d/%d\n", wat, c);
  221. }
  222. /* sptab needs to interpolate 2 tables. */
  223. if (tab1 != tab2) {
  224. c1 = sptab_lookup(tab1, voltage, degree);
  225. c2 = sptab_lookup(tab2, voltage, degree);
  226. interpolate_table(tspt, c1, c2, wat, tab1, tab2);
  227. }
  228. /* update to global data */
  229. *spt = *tspt;
  230. return 0;
  231. }
  232. #define MT_SPOWER_UT 1
  233. #if defined(MT_SPOWER_UT)
  234. void mt_spower_ut(void)
  235. {
  236. int v, t, p, i;
  237. for (i = 0; i < MT_SPOWER_MAX; i++) {
  238. sptbl_t *spt = &sptab[i];
  239. switch (i) {
  240. case MT_SPOWER_CPU:
  241. SPOWER_INFO("[SPOWER] - This is MT_SPOWER_CPU\n");
  242. break;
  243. case MT_SPOWER_VCORE:
  244. SPOWER_INFO("[SPOWER] - This is MT_SPOWER_VCORE\n");
  245. break;
  246. case MT_SPOWER_LTE:
  247. SPOWER_INFO("[SPOWER] - This is MT_SPOWER_LTE\n");
  248. break;
  249. default:
  250. break;
  251. }
  252. v = 750;
  253. t = 22;
  254. p = sptab_lookup(spt, v, t);
  255. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  256. v = 750;
  257. t = 25;
  258. p = sptab_lookup(spt, v, t);
  259. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  260. v = 750;
  261. t = 28;
  262. p = sptab_lookup(spt, v, t);
  263. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  264. v = 750;
  265. t = 82;
  266. p = sptab_lookup(spt, v, t);
  267. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  268. v = 750;
  269. t = 120;
  270. p = sptab_lookup(spt, v, t);
  271. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  272. v = 820;
  273. t = 22;
  274. p = sptab_lookup(spt, v, t);
  275. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  276. v = 820;
  277. t = 25;
  278. p = sptab_lookup(spt, v, t);
  279. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  280. v = 820;
  281. t = 28;
  282. p = sptab_lookup(spt, v, t);
  283. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  284. v = 820;
  285. t = 82;
  286. p = sptab_lookup(spt, v, t);
  287. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  288. v = 820;
  289. t = 120;
  290. p = sptab_lookup(spt, v, t);
  291. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  292. v = 1200;
  293. t = 22;
  294. p = sptab_lookup(spt, v, t);
  295. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  296. v = 1200;
  297. t = 25;
  298. p = sptab_lookup(spt, v, t);
  299. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  300. v = 1200;
  301. t = 28;
  302. p = sptab_lookup(spt, v, t);
  303. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  304. v = 1200;
  305. t = 82;
  306. p = sptab_lookup(spt, v, t);
  307. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  308. v = 1200;
  309. t = 120;
  310. p = sptab_lookup(spt, v, t);
  311. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  312. v = 950;
  313. t = 80;
  314. p = sptab_lookup(spt, v, t);
  315. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  316. v = 1000;
  317. t = 85;
  318. p = sptab_lookup(spt, v, t);
  319. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  320. v = 1150;
  321. t = 105;
  322. p = sptab_lookup(spt, v, t);
  323. SPOWER_INFO("v/t/p: %d/%d/%d\n", v, t, p);
  324. switch (i) {
  325. case MT_SPOWER_CPU:
  326. SPOWER_INFO("[SPOWER] - MT_SPOWER_CPU Done\n");
  327. break;
  328. case MT_SPOWER_VCORE:
  329. SPOWER_INFO("[SPOWER] - MT_SPOWER_VCORE Done\n");
  330. break;
  331. case MT_SPOWER_LTE:
  332. SPOWER_INFO("[SPOWER] - MT_SPOWER_LTE Done\n");
  333. break;
  334. default:
  335. break;
  336. }
  337. }
  338. }
  339. #endif
  340. int mt_spower_init(void)
  341. {
  342. #define DEVINFO_IDX0 (14)
  343. #define DEVINFO_MP1_BIT (0)
  344. #define DEVINFO_MP0_BIT (8)
  345. #define DEVINFO_LTE_BIT (16)
  346. int devinfo = 0;
  347. int lte;
  348. int cpu;
  349. int vcore;
  350. /* avoid side effect from multiple invocation */
  351. if (tab_validate(&sptab[MT_SPOWER_CPU]))
  352. return 0;
  353. /* ptp_read(0xF020618C); */
  354. devinfo = (int)get_devinfo_with_index(DEVINFO_IDX0);
  355. cpu = (devinfo >> DEVINFO_MP1_BIT) & 0x0ff;
  356. vcore = (devinfo >> DEVINFO_MP0_BIT) & 0x0ff;
  357. lte = (devinfo >> DEVINFO_LTE_BIT) & 0x0ff;
  358. SPOWER_INFO("[SPOWER] - cpu/vcore/lte => 0x%x/0x%x/0x%x\n", cpu, vcore, lte);
  359. if (devinfo != 0) {
  360. lte = (int)devinfo_table[lte];
  361. cpu = (int)devinfo_table[cpu];
  362. vcore = (int)devinfo_table[vcore];
  363. SPOWER_INFO("[SPOWER] - cpu/vcore/lte => %d/%d/%d\n", cpu, vcore, lte);
  364. lte = (int)(lte * 1250 / 1000);
  365. cpu = (int)(cpu * 1250 / 1000);
  366. vcore = (int)(vcore * 1250 / 1000);
  367. } else {
  368. cpu = 100;
  369. lte = 162;
  370. vcore = 300;
  371. }
  372. SPOWER_INFO("[SPOWER] - cpu/vcore/lte => %d/%d/%d\n", cpu, vcore, lte);
  373. SPOWER_INFO("[SPOWER] - MT_SPOWER_CPU\n");
  374. mt_spower_make_table(&sptab[MT_SPOWER_CPU], &cpu_spower_raw, cpu, 1250, 30);
  375. SPOWER_INFO("[SPOWER] - MT_SPOWER_VCORE\n");
  376. mt_spower_make_table(&sptab[MT_SPOWER_VCORE], &vcore_spower_raw, vcore, 1250, 30);
  377. SPOWER_INFO("[SPOWER] - MT_SPOWER_LTE\n");
  378. mt_spower_make_table(&sptab[MT_SPOWER_LTE], &lte_spower_raw, lte, 1250, 30);
  379. SPOWER_INFO("[SPOWER] - Start SPOWER UT!\n");
  380. mt_spower_ut();
  381. SPOWER_INFO("[SPOWER] - End SPOWER UT!\n");
  382. return 0;
  383. }
  384. late_initcall(mt_spower_init);
  385. /* return 0, means sptab is not yet ready. */
  386. int mt_spower_get_leakage(int dev, int vol, int deg)
  387. {
  388. BUG_ON(!(dev < MT_SPOWER_MAX));
  389. if (!tab_validate(&sptab[dev]))
  390. return 0;
  391. return sptab_lookup(&sptab[dev], vol, deg);
  392. }
  393. EXPORT_SYMBOL(mt_spower_get_leakage);