lastbus_v1.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #include <linux/module.h>
  2. #include <linux/slab.h>
  3. #include <mt-plat/mt_io.h>
  4. #include <asm/io.h>
  5. #include "../lastbus.h"
  6. #include "lastbus_v1.h"
  7. struct lastbus_imp {
  8. struct lastbus_plt plt;
  9. void __iomem *toprgu_reg;
  10. };
  11. #define to_lastbus_imp(p) container_of((p), struct lastbus_imp, plt)
  12. static int dump(struct lastbus_plt *plt, char *buf, int len)
  13. {
  14. void __iomem *mcu_base = plt->common->mcu_base;
  15. void __iomem *peri_base = plt->common->peri_base;
  16. unsigned long meter;
  17. unsigned long debug_raw;
  18. unsigned long w_counter, r_counter, c_counter;
  19. char *ptr = buf;
  20. int i;
  21. if (!mcu_base && !peri_base)
  22. return -1;
  23. if (mcu_base) {
  24. for (i = 0; i <= NUM_MASTER_PORT-1; ++i) {
  25. debug_raw = readl(IOMEM(mcu_base + BUS_MCU_M0 + 4 * i));
  26. meter = readl(IOMEM(mcu_base + BUS_MCU_M0_M + 4 * i));
  27. w_counter = meter & 0x3f;
  28. r_counter = (meter >> 8) & 0x3f;
  29. if ((w_counter != 0) || (r_counter != 0)) {
  30. ptr += sprintf(ptr, "[LAST BUS] Master %d: ", i);
  31. ptr += sprintf(ptr, "aw_pending_counter = 0x%02lx, ar_pending_counter = 0x%02lx\n",
  32. w_counter, r_counter);
  33. ptr += sprintf(ptr, "STATUS = %03lx\n", debug_raw & 0x3ff);
  34. }
  35. }
  36. for (i = 1; i <= NUM_SLAVE_PORT; ++i) {
  37. debug_raw = readl(IOMEM(mcu_base + BUS_MCU_S1 + 4 * (i-1)));
  38. meter = readl(IOMEM(mcu_base + BUS_MCU_S1_M + 4 * (i-1)));
  39. w_counter = meter & 0x3f;
  40. r_counter = (meter >> 8) & 0x3f;
  41. c_counter = (meter >> 16) & 0x3f;
  42. if ((w_counter != 0) || (r_counter != 0) || (c_counter != 0)) {
  43. ptr += sprintf(ptr, "[LAST BUS] Slave %d: ", i);
  44. ptr += sprintf(ptr,
  45. "aw_pending_counter = 0x%02lx, ar_pending_counter = 0x%02lx, ac_pending_counter = 0x%02lx\n",
  46. w_counter, r_counter, c_counter);
  47. if (i <= 2)
  48. ptr += sprintf(ptr, "STATUS = %04lx\n", debug_raw & 0x3fff);
  49. else
  50. ptr += sprintf(ptr, "STATUS = %04lx\n", debug_raw & 0xffff);
  51. }
  52. }
  53. }
  54. if (peri_base) {
  55. if (readl(IOMEM(peri_base+BUS_PERI_R1)) & 0x1) {
  56. ptr += sprintf(ptr, "[LAST BUS] PERISYS TIMEOUT:\n");
  57. for (i = 0; i <= NUM_MON-1; ++i)
  58. ptr += sprintf(ptr, "PERI MON%d = %04x\n", i, readl(IOMEM(peri_base+BUS_PERI_MON+4*i)));
  59. }
  60. }
  61. return 0;
  62. }
  63. static int enable(struct lastbus_plt *plt)
  64. {
  65. void __iomem *peri_base = plt->common->peri_base;
  66. if (!peri_base)
  67. return -1;
  68. /* timeout set to around 130 ms */
  69. writel(0x3fff, IOMEM(peri_base+BUS_PERI_R0));
  70. /* enable the perisys debugging funcationality */
  71. writel(0xc, IOMEM(peri_base+BUS_PERI_R1));
  72. return 0;
  73. }
  74. static int test_show(char *buf)
  75. {
  76. return snprintf(buf, PAGE_SIZE, "==LAST BUS TEST==\n1. test case 1\n2. test case 2\n3. test case 3\n");
  77. }
  78. static int soc_hang_test(unsigned long addr_to_set, unsigned long addr_to_access, unsigned int flag)
  79. {
  80. void __iomem *p1 = ioremap(addr_to_set, 0x4);
  81. void __iomem *p2 = ioremap(addr_to_access, 0x4);
  82. /* *iNFRA_TOPAXI_PROTECTEN (0x1000_1220) |= 0x40 //isolate MFG */
  83. writel(readl(p1) | (flag), p1);
  84. /* Access MM area */
  85. readl(p2);
  86. /* clear the setting */
  87. writel(readl(p1) & ~(flag), p1);
  88. pr_err("[LAST BUS] SOC hang test failed\n");
  89. return 1;
  90. }
  91. static int mcusys_hang_test(unsigned long addr_to_set, unsigned int flag)
  92. {
  93. void __iomem *p1 = ioremap(addr_to_set, 0x4);
  94. int data_on_dram;
  95. /* XXX: Turn on 8 cores before test */
  96. /* *MP1_AXI_CONFIG (0x1020_022C) |= 0x10; //disable cluster1 snoop channel */
  97. writel(readl(p1) | (flag), p1);
  98. /* Access any DRAM address (snooping) or invalidate TLB (DVM) */
  99. data_on_dram = 1;
  100. mb();
  101. pr_err("[LAST BUS] MCUSYS hang test failed\n");
  102. return 1;
  103. }
  104. static int perisys_hang_test(unsigned long addr_to_set, unsigned long addr_to_access, unsigned int flag)
  105. {
  106. void __iomem *p1 = ioremap(addr_to_set, 0x4);
  107. void __iomem *p2 = ioremap(addr_to_access, 0x4);
  108. writel(readl(p1) | (flag), p1);
  109. readl(p2);
  110. return 1;
  111. }
  112. static int test(struct lastbus_plt *plt, int test_case)
  113. {
  114. switch (test_case) {
  115. case 1:
  116. soc_hang_test(0x10001220, 0x14000000, 0x40);
  117. break;
  118. case 2:
  119. mcusys_hang_test(0x1020022C, 0x10);
  120. break;
  121. case 3:
  122. perisys_hang_test(0x10001088, 0x11230000, 1<<2);
  123. break;
  124. default:
  125. break;
  126. }
  127. return 0;
  128. }
  129. static struct lastbus_plt_operations lastbus_ops = {
  130. .dump = dump,
  131. .test = test,
  132. .test_show = test_show,
  133. .enable = enable,
  134. };
  135. static int __init lastbus_init(void)
  136. {
  137. struct lastbus_imp *drv = NULL;
  138. int ret = 0;
  139. drv = kzalloc(sizeof(struct lastbus_imp), GFP_KERNEL);
  140. if (!drv)
  141. return -ENOMEM;
  142. drv->plt.ops = &lastbus_ops;
  143. drv->plt.min_buf_len = 2048; /* TODO: can calculate the len by how many levels of bt we want */
  144. ret = lastbus_register(&drv->plt);
  145. if (ret) {
  146. pr_err("%s:%d: lastbus_register failed\n", __func__, __LINE__);
  147. goto register_lastbus_err;
  148. }
  149. return 0;
  150. register_lastbus_err:
  151. kfree(drv);
  152. return ret;
  153. }
  154. core_initcall(lastbus_init);