spram.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. * MIPS SPRAM support
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version
  7. * 2 of the License, or (at your option) any later version.
  8. *
  9. * Copyright (C) 2007, 2008 MIPS Technologies, Inc.
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/ptrace.h>
  13. #include <linux/stddef.h>
  14. #include <asm/fpu.h>
  15. #include <asm/mipsregs.h>
  16. #include <asm/r4kcache.h>
  17. #include <asm/hazards.h>
  18. /*
  19. * These definitions are correct for the 24K/34K/74K SPRAM sample
  20. * implementation. The 4KS interpreted the tags differently...
  21. */
  22. #define SPRAM_TAG0_ENABLE 0x00000080
  23. #define SPRAM_TAG0_PA_MASK 0xfffff000
  24. #define SPRAM_TAG1_SIZE_MASK 0xfffff000
  25. #define SPRAM_TAG_STRIDE 8
  26. #define ERRCTL_SPRAM (1 << 28)
  27. /* errctl access */
  28. #define read_c0_errctl(x) read_c0_ecc(x)
  29. #define write_c0_errctl(x) write_c0_ecc(x)
  30. /*
  31. * Different semantics to the set_c0_* function built by __BUILD_SET_C0
  32. */
  33. static unsigned int bis_c0_errctl(unsigned int set)
  34. {
  35. unsigned int res;
  36. res = read_c0_errctl();
  37. write_c0_errctl(res | set);
  38. return res;
  39. }
  40. static void ispram_store_tag(unsigned int offset, unsigned int data)
  41. {
  42. unsigned int errctl;
  43. /* enable SPRAM tag access */
  44. errctl = bis_c0_errctl(ERRCTL_SPRAM);
  45. ehb();
  46. write_c0_taglo(data);
  47. ehb();
  48. cache_op(Index_Store_Tag_I, CKSEG0|offset);
  49. ehb();
  50. write_c0_errctl(errctl);
  51. ehb();
  52. }
  53. static unsigned int ispram_load_tag(unsigned int offset)
  54. {
  55. unsigned int data;
  56. unsigned int errctl;
  57. /* enable SPRAM tag access */
  58. errctl = bis_c0_errctl(ERRCTL_SPRAM);
  59. ehb();
  60. cache_op(Index_Load_Tag_I, CKSEG0 | offset);
  61. ehb();
  62. data = read_c0_taglo();
  63. ehb();
  64. write_c0_errctl(errctl);
  65. ehb();
  66. return data;
  67. }
  68. static void dspram_store_tag(unsigned int offset, unsigned int data)
  69. {
  70. unsigned int errctl;
  71. /* enable SPRAM tag access */
  72. errctl = bis_c0_errctl(ERRCTL_SPRAM);
  73. ehb();
  74. write_c0_dtaglo(data);
  75. ehb();
  76. cache_op(Index_Store_Tag_D, CKSEG0 | offset);
  77. ehb();
  78. write_c0_errctl(errctl);
  79. ehb();
  80. }
  81. static unsigned int dspram_load_tag(unsigned int offset)
  82. {
  83. unsigned int data;
  84. unsigned int errctl;
  85. errctl = bis_c0_errctl(ERRCTL_SPRAM);
  86. ehb();
  87. cache_op(Index_Load_Tag_D, CKSEG0 | offset);
  88. ehb();
  89. data = read_c0_dtaglo();
  90. ehb();
  91. write_c0_errctl(errctl);
  92. ehb();
  93. return data;
  94. }
  95. static void probe_spram(char *type,
  96. unsigned int base,
  97. unsigned int (*read)(unsigned int),
  98. void (*write)(unsigned int, unsigned int))
  99. {
  100. unsigned int firstsize = 0, lastsize = 0;
  101. unsigned int firstpa = 0, lastpa = 0, pa = 0;
  102. unsigned int offset = 0;
  103. unsigned int size, tag0, tag1;
  104. unsigned int enabled;
  105. int i;
  106. /*
  107. * The limit is arbitrary but avoids the loop running away if
  108. * the SPRAM tags are implemented differently
  109. */
  110. for (i = 0; i < 8; i++) {
  111. tag0 = read(offset);
  112. tag1 = read(offset+SPRAM_TAG_STRIDE);
  113. pr_debug("DBG %s%d: tag0=%08x tag1=%08x\n",
  114. type, i, tag0, tag1);
  115. size = tag1 & SPRAM_TAG1_SIZE_MASK;
  116. if (size == 0)
  117. break;
  118. if (i != 0) {
  119. /* tags may repeat... */
  120. if ((pa == firstpa && size == firstsize) ||
  121. (pa == lastpa && size == lastsize))
  122. break;
  123. }
  124. /* Align base with size */
  125. base = (base + size - 1) & ~(size-1);
  126. /* reprogram the base address base address and enable */
  127. tag0 = (base & SPRAM_TAG0_PA_MASK) | SPRAM_TAG0_ENABLE;
  128. write(offset, tag0);
  129. base += size;
  130. /* reread the tag */
  131. tag0 = read(offset);
  132. pa = tag0 & SPRAM_TAG0_PA_MASK;
  133. enabled = tag0 & SPRAM_TAG0_ENABLE;
  134. if (i == 0) {
  135. firstpa = pa;
  136. firstsize = size;
  137. }
  138. lastpa = pa;
  139. lastsize = size;
  140. if (strcmp(type, "DSPRAM") == 0) {
  141. unsigned int *vp = (unsigned int *)(CKSEG1 | pa);
  142. unsigned int v;
  143. #define TDAT 0x5a5aa5a5
  144. vp[0] = TDAT;
  145. vp[1] = ~TDAT;
  146. mb();
  147. v = vp[0];
  148. if (v != TDAT)
  149. printk(KERN_ERR "vp=%p wrote=%08x got=%08x\n",
  150. vp, TDAT, v);
  151. v = vp[1];
  152. if (v != ~TDAT)
  153. printk(KERN_ERR "vp=%p wrote=%08x got=%08x\n",
  154. vp+1, ~TDAT, v);
  155. }
  156. pr_info("%s%d: PA=%08x,Size=%08x%s\n",
  157. type, i, pa, size, enabled ? ",enabled" : "");
  158. offset += 2 * SPRAM_TAG_STRIDE;
  159. }
  160. }
  161. void spram_config(void)
  162. {
  163. unsigned int config0;
  164. switch (current_cpu_type()) {
  165. case CPU_24K:
  166. case CPU_34K:
  167. case CPU_74K:
  168. case CPU_1004K:
  169. case CPU_1074K:
  170. case CPU_INTERAPTIV:
  171. case CPU_PROAPTIV:
  172. case CPU_P5600:
  173. case CPU_QEMU_GENERIC:
  174. config0 = read_c0_config();
  175. /* FIXME: addresses are Malta specific */
  176. if (config0 & (1<<24)) {
  177. probe_spram("ISPRAM", 0x1c000000,
  178. &ispram_load_tag, &ispram_store_tag);
  179. }
  180. if (config0 & (1<<23))
  181. probe_spram("DSPRAM", 0x1c100000,
  182. &dspram_load_tag, &dspram_store_tag);
  183. }
  184. }