emi-addr2dram.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein is
  5. * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
  6. * the prior written permission of MediaTek inc. and/or its licensors, any
  7. * reproduction, modification, use or disclosure of MediaTek Software, and
  8. * information contained herein, in whole or in part, shall be strictly
  9. * prohibited.
  10. *
  11. * MediaTek Inc. (C) 2016. All rights reserved.
  12. *
  13. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  14. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  15. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
  16. * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
  17. * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  19. * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
  20. * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
  21. * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
  22. * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
  23. * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
  24. * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
  25. * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
  26. * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  27. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
  28. * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
  29. * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
  30. * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
  31. * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  32. *
  33. * The following software/firmware and/or related documentation ("MediaTek
  34. * Software") have been modified by MediaTek Inc. All revisions are subject to
  35. * any receiver's applicable license agreements with MediaTek Inc.
  36. */
  37. #include <debug.h>
  38. #include <lk_builtin_dtb.h>
  39. #include <libfdt.h>
  40. #include <reg.h>
  41. #include <emi-addr2dram.h>
  42. #define MTK_EMI_DRAM_OFFSET 0x40000000
  43. #define MTK_EMI_DISPATCH_RULE 0x0
  44. #define MTK_EMI_HASH_RULE 0x7
  45. const char *emicen_compatible[] = {
  46. "/soc/emicen",
  47. "/emicen",
  48. NULL
  49. };
  50. static unsigned int emi_a2d_con_offset[] = {
  51. 0x00, 0x28, 0x38, 0x3c, 0x50,
  52. };
  53. static unsigned long offset;
  54. static unsigned long max_mb;
  55. static unsigned long disph = MTK_EMI_DISPATCH_RULE;
  56. static unsigned int magics[8];
  57. static unsigned int cas;
  58. static unsigned long hash = MTK_EMI_HASH_RULE;
  59. static unsigned int chab_rk0_sz, chab_rk1_sz;
  60. static unsigned int chcd_rk0_sz, chcd_rk1_sz;
  61. static unsigned int channels;
  62. static unsigned int dualrk_ch0, dualrk_ch1;
  63. static unsigned int chn_hash_lsb, chnpos;
  64. static unsigned int chab_row_mask[2], chcd_row_mask[2];
  65. static unsigned int chab_col_mask[2], chcd_col_mask[2];
  66. static unsigned int dw32;
  67. static unsigned int chn_4bank_mode;
  68. static inline bool test_bit(long nr, const volatile unsigned long *addr)
  69. {
  70. return ((*addr >> nr) & 1)? 1 : 0;
  71. }
  72. static inline void clear_bit(unsigned int nr, volatile unsigned long *p)
  73. {
  74. *p &= ~(1UL << nr);
  75. }
  76. static inline unsigned long __ffs(unsigned long word)
  77. {
  78. return (word & (~word + 1));
  79. }
  80. static void prepare_a2d(void)
  81. {
  82. static int prepared = 0;
  83. void *fdt;
  84. int off, len, array_len, i;
  85. unsigned int *data;
  86. unsigned int emi_con_base;
  87. const unsigned int mask = 0x0000000f;
  88. unsigned int emi_cona, emi_conf, emi_conh, emi_conh_2nd, emi_conk;
  89. unsigned int tmp;
  90. if (prepared)
  91. return;
  92. array_len = sizeof(emicen_compatible) / sizeof(emicen_compatible[0]);
  93. fdt = get_lk_overlayed_dtb();
  94. for (i = 0; i < array_len; i++) {
  95. off = fdt_path_offset(fdt, emicen_compatible[i]);
  96. if (off >= 0)
  97. break;
  98. }
  99. if (i >= array_len) {
  100. dprintf(CRITICAL, "emi addr2dram couldn't find the emicen node)\n");
  101. return;
  102. }
  103. data = (unsigned int *)fdt_getprop(fdt, off, "reg", &len);
  104. if (!data || !len) {
  105. dprintf(CRITICAL, "emi addr2dram couldn't find property reg\n");
  106. return;
  107. }
  108. emi_con_base = fdt32_to_cpu(data[1]);
  109. array_len = sizeof(emi_a2d_con_offset) / sizeof(emi_a2d_con_offset[0]);
  110. data = (unsigned int *)fdt_getprop(fdt, off, "a2d_conf_offset", &len);
  111. if (data && len) {
  112. for (i = 0; i < array_len; i++)
  113. emi_a2d_con_offset[i] = fdt32_to_cpu(data[i]);
  114. }
  115. emi_cona = readl(emi_con_base + emi_a2d_con_offset[0]);
  116. emi_conf = readl(emi_con_base + emi_a2d_con_offset[1]);
  117. emi_conh = readl(emi_con_base + emi_a2d_con_offset[2]);
  118. emi_conh_2nd = readl(emi_con_base + emi_a2d_con_offset[3]);
  119. emi_conk = readl(emi_con_base + emi_a2d_con_offset[4]);
  120. data = (unsigned int *)fdt_getprop(fdt, off, "a2d_disph", &len);
  121. if (data && len)
  122. disph = fdt32_to_cpu(*data);
  123. data = (unsigned int *)fdt_getprop(fdt, off, "a2d_hash", &len);
  124. if (data && len)
  125. hash = fdt32_to_cpu(*data);
  126. offset = MTK_EMI_DRAM_OFFSET;
  127. magics[0] = emi_conf & mask;
  128. magics[1] = (emi_conf >> 4) & mask;
  129. magics[2] = (emi_conf >> 8) & mask;
  130. magics[3] = (emi_conf >> 12) & mask;
  131. magics[4] = (emi_conf >> 16) & mask;
  132. magics[5] = (emi_conf >> 20) & mask;
  133. magics[6] = (emi_conf >> 24) & mask;
  134. magics[7] = (emi_conf >> 28) & mask;
  135. dw32 = test_bit(1, (unsigned long *)&emi_cona) ? 1 : 0;
  136. channels = (emi_cona >> 8) & 0x3;
  137. cas = (emi_cona >> 18) & 0x3;
  138. cas += dw32 << 2;
  139. cas += ((emi_cona >> 26) & 1) << 3;
  140. cas = cas << 28;
  141. cas = cas << channels;
  142. dualrk_ch0 = test_bit(17, (unsigned long *)&emi_cona) ? 1 : 0;
  143. dualrk_ch1 = test_bit(16, (unsigned long *)&emi_cona) ? 1 : 0;
  144. chn_hash_lsb = 7 + (hash & (~hash + 1));
  145. if (hash)
  146. chnpos = chn_hash_lsb;
  147. else {
  148. chnpos = test_bit(3, (unsigned long *)&emi_cona) ? 2 : 0;
  149. chnpos |= test_bit(2, (unsigned long *)&emi_cona) ? 1 : 0;
  150. }
  151. tmp = (emi_conh >> 16) & 0xf;
  152. tmp += ((emi_conk >> 16) & 0xf) << 4;
  153. if (tmp)
  154. chab_rk0_sz = tmp << 8;
  155. else {
  156. tmp = (emi_cona >> 4) & 0x3;
  157. tmp += (emi_cona >> 12) & 0x3;
  158. tmp += test_bit(24, (unsigned long *)&emi_cona) ? 4 : 0;
  159. tmp += dw32;
  160. tmp += 7;
  161. chab_rk0_sz = 1 << tmp;
  162. }
  163. tmp = (emi_conh >> 20) & 0xf;
  164. tmp += ((emi_conk >> 20) & 0xf) << 4;
  165. if (tmp)
  166. chab_rk1_sz = tmp << 8;
  167. else if (!test_bit(17, (unsigned long *)&emi_cona))
  168. chab_rk1_sz = 0;
  169. else {
  170. tmp = (emi_cona >> 6) & 0x3;
  171. tmp += (emi_cona >> 14) & 0x3;
  172. tmp += test_bit(25, (unsigned long *)&emi_cona) ? 4 : 0;
  173. tmp += dw32;
  174. tmp += 7;
  175. chab_rk1_sz = 1 << tmp;
  176. }
  177. tmp = (emi_conh >> 24) & 0xf;
  178. tmp += ((emi_conk >> 24) & 0xf) << 4;
  179. if (tmp)
  180. chcd_rk0_sz = tmp << 8;
  181. else {
  182. tmp = (emi_cona >> 20) & 0x3;
  183. tmp += (emi_cona >> 28) & 0x3;
  184. tmp += test_bit(4, (unsigned long *)&emi_conh) ? 4 : 0;
  185. tmp += dw32;
  186. tmp += 7;
  187. chcd_rk0_sz = 1 << tmp;
  188. }
  189. tmp = (emi_conh >> 28) & 0xf;
  190. tmp += ((emi_conk >> 28) & 0xf) << 4;
  191. if (tmp)
  192. chcd_rk1_sz = tmp << 8;
  193. else if (!test_bit(16, (unsigned long *)&emi_cona))
  194. chcd_rk1_sz = 0;
  195. else {
  196. tmp = (emi_cona >> 22) & 0x3;
  197. tmp += (emi_cona >> 30) & 0x3;
  198. tmp += test_bit(5, (unsigned long *)&emi_conh) ? 4 : 0;
  199. tmp += dw32;
  200. tmp += 7;
  201. chcd_rk1_sz = 1 << tmp;
  202. }
  203. max_mb = chab_rk0_sz + chab_rk1_sz;
  204. max_mb += chcd_rk0_sz + chcd_rk0_sz;
  205. if ((channels > 1) || (disph > 0))
  206. max_mb *= 2;
  207. chab_row_mask[0] = (emi_cona >> 12) & 3;
  208. chab_row_mask[0] += test_bit(24, (unsigned long *)&emi_cona) ? 4 : 0;
  209. chab_row_mask[0] += 13;
  210. chab_row_mask[1] = (emi_cona >> 14) & 3;
  211. chab_row_mask[1] += test_bit(25, (unsigned long *)&emi_cona) ? 4 : 0;
  212. chab_row_mask[1] += 13;
  213. chcd_row_mask[0] = (emi_cona >> 28) & 3;
  214. chcd_row_mask[0] += test_bit(4, (unsigned long *)&emi_conh) ? 4 : 0;
  215. chcd_row_mask[0] += 13;
  216. chcd_row_mask[1] = (emi_cona >> 30) & 3;
  217. chcd_row_mask[1] += test_bit(5, (unsigned long *)&emi_conh) ? 4 : 0;
  218. chcd_row_mask[1] += 13;
  219. chab_col_mask[0] = (emi_cona >> 4) & 3;
  220. chab_col_mask[0] += 9;
  221. chab_col_mask[1] = (emi_cona >> 6) & 3;
  222. chab_col_mask[1] += 9;
  223. chcd_col_mask[0] = (emi_cona >> 20) & 3;
  224. chcd_col_mask[0] += 9;
  225. chcd_col_mask[1] = (emi_cona >> 22) & 3;
  226. chcd_col_mask[1] += 9;
  227. chn_4bank_mode = test_bit(6, (unsigned long *)&emi_conh_2nd) ? 1 : 0;
  228. prepared = 1;
  229. }
  230. static unsigned int use_a2d_magic(unsigned long addr, unsigned int bit)
  231. {
  232. unsigned long magic;
  233. unsigned int ret;
  234. magic = magics[((bit >= 9) & (bit <= 16)) ? (bit - 9) : 0];
  235. ret = test_bit(bit, &addr) ? 1 : 0;
  236. ret ^= (test_bit(16, &addr) && test_bit(0, &magic)) ? 1 : 0;
  237. ret ^= (test_bit(17, &addr) && test_bit(1, &magic)) ? 1 : 0;
  238. ret ^= (test_bit(18, &addr) && test_bit(2, &magic)) ? 1 : 0;
  239. ret ^= (test_bit(19, &addr) && test_bit(3, &magic)) ? 1 : 0;
  240. return ret;
  241. }
  242. int emi_addr2dram(unsigned long addr, struct emi_addr_map *map)
  243. {
  244. unsigned int tmp;
  245. unsigned long saddr, bfraddr, chnaddr;
  246. unsigned int max_rk0_sz;
  247. unsigned int row_mask, col_mask;
  248. bool ch_ab_not_cd;
  249. prepare_a2d();
  250. if (!map)
  251. return -1;
  252. else {
  253. map->emi = -1;
  254. map->channel = -1;
  255. map->rank = -1;
  256. map->bank = -1;
  257. map->row = -1;
  258. map->column = -1;
  259. }
  260. if (addr < offset)
  261. return -1;
  262. else
  263. addr -= offset;
  264. if ((addr >> 20) > max_mb)
  265. return -1;
  266. tmp = (test_bit(8, &addr) & test_bit(0, &disph)) ? 1 : 0;
  267. tmp ^= (test_bit(9, &addr) & test_bit(1, &disph)) ? 1 : 0;
  268. tmp ^= (test_bit(10, &addr) & test_bit(2, &disph)) ? 1 : 0;
  269. tmp ^= (test_bit(11, &addr) & test_bit(3, &disph)) ? 1 : 0;
  270. map->emi = tmp;
  271. saddr = addr;
  272. clear_bit(9, &saddr);
  273. clear_bit(10, &saddr);
  274. clear_bit(11, &saddr);
  275. clear_bit(12, &saddr);
  276. clear_bit(13, &saddr);
  277. clear_bit(14, &saddr);
  278. clear_bit(15, &saddr);
  279. clear_bit(16, &saddr);
  280. saddr |= use_a2d_magic(addr, 9) << 9;
  281. saddr |= use_a2d_magic(addr, 10) << 10;
  282. saddr |= use_a2d_magic(addr, 11) << 11;
  283. saddr |= use_a2d_magic(addr, 12) << 12;
  284. saddr |= use_a2d_magic(addr, 13) << 13;
  285. saddr |= use_a2d_magic(addr, 14) << 14;
  286. saddr |= use_a2d_magic(addr, 15) << 15;
  287. saddr |= use_a2d_magic(addr, 16) << 16;
  288. if (disph <= 0)
  289. bfraddr = saddr;
  290. else {
  291. tmp = 7 + __ffs(disph);
  292. bfraddr = (saddr >> (tmp + 1)) << tmp;
  293. bfraddr += saddr & ((1 << tmp) - 1);
  294. }
  295. if (bfraddr < cas)
  296. return -1;
  297. if (!channels)
  298. map->channel = channels;
  299. else if (hash) {
  300. tmp = (test_bit(8, &addr) && test_bit(0, &hash)) ? 1 : 0;
  301. tmp ^= (test_bit(9, &addr) && test_bit(1, &hash)) ? 1 : 0;
  302. tmp ^= (test_bit(10, &addr) && test_bit(2, &hash)) ? 1 : 0;
  303. tmp ^= (test_bit(11, &addr) && test_bit(3, &hash)) ? 1 : 0;
  304. map->channel = tmp;
  305. } else {
  306. if (channels == 1) {
  307. tmp = 0;
  308. switch (chnpos) {
  309. case 0:
  310. tmp = 7;
  311. break;
  312. case 1:
  313. tmp = 8;
  314. break;
  315. case 2:
  316. tmp = 9;
  317. break;
  318. case 3:
  319. tmp = 12;
  320. break;
  321. default:
  322. return -1;
  323. }
  324. map->channel = (bfraddr >> tmp) % 2;
  325. } else if (channels == 2) {
  326. tmp = 0;
  327. switch (chnpos) {
  328. case 0:
  329. tmp = 7;
  330. break;
  331. case 1:
  332. tmp = 8;
  333. break;
  334. case 2:
  335. tmp = 9;
  336. break;
  337. case 3:
  338. tmp = 12;
  339. break;
  340. default:
  341. return -1;
  342. }
  343. map->channel = (bfraddr >> tmp) % 4;
  344. } else {
  345. return -1;
  346. }
  347. }
  348. if (map->channel > 1)
  349. ch_ab_not_cd = 0;
  350. else {
  351. if (map->channel == 1)
  352. ch_ab_not_cd = (channels > 1) ? 1 : 0;
  353. else
  354. ch_ab_not_cd = 1;
  355. }
  356. max_rk0_sz = (ch_ab_not_cd) ? chab_rk0_sz : chcd_rk0_sz;
  357. max_rk0_sz = max_rk0_sz << 20;
  358. if (!channels)
  359. chnaddr = bfraddr;
  360. else if (chnpos > 3) {
  361. tmp = chn_hash_lsb;
  362. chnaddr = bfraddr >> (tmp + 1);
  363. chnaddr = chnaddr << tmp;
  364. chnaddr += bfraddr & ((1 << tmp) - 1);
  365. } else if (channels == 1 || channels == 2) {
  366. tmp = 0;
  367. switch (chnpos) {
  368. case 0:
  369. tmp = 7;
  370. break;
  371. case 1:
  372. tmp = 8;
  373. break;
  374. case 2:
  375. tmp = 9;
  376. break;
  377. case 3:
  378. tmp = 12;
  379. break;
  380. default:
  381. break;
  382. }
  383. chnaddr = bfraddr >> (tmp + (channels -1));
  384. chnaddr = chnaddr << tmp;
  385. chnaddr += bfraddr & ((1 << tmp) - 1);
  386. } else {
  387. return -1;
  388. }
  389. if ((map->channel) ? !dualrk_ch1 : !dualrk_ch0)
  390. map->rank = 0;
  391. else {
  392. if (chnaddr > max_rk0_sz)
  393. map->rank = 1;
  394. else
  395. map->rank = 0;
  396. }
  397. row_mask = (ch_ab_not_cd) ?
  398. ((map->rank) ? chab_row_mask[1] : chab_row_mask[0]) :
  399. ((map->rank) ? chcd_row_mask[1] : chcd_row_mask[0]);
  400. col_mask = (ch_ab_not_cd) ?
  401. ((map->rank) ? chab_col_mask[1] : chab_col_mask[0]) :
  402. ((map->rank) ? chcd_col_mask[1] : chcd_col_mask[0]);
  403. tmp = chnaddr - (max_rk0_sz * map->rank);
  404. tmp /= 1 << (dw32 + 1 + col_mask + 3);
  405. tmp &= (1 << row_mask) - 1;
  406. map->row = tmp;
  407. tmp = chnaddr;
  408. tmp /= 1 << (dw32 + 1 + col_mask);
  409. tmp &= ((!chn_4bank_mode) ? 8 : 4) - 1;
  410. map->bank = tmp;
  411. tmp = chnaddr;
  412. tmp /= 1 << (dw32 + 1);
  413. tmp &= (1 << col_mask) - 1;
  414. map->column = tmp;
  415. return 0;
  416. }