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