Commit | Line | Data |
---|---|---|
6fa3eb70 S |
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 | } |