qbman_private.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * Copyright (C) 2014 Freescale Semiconductor
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. /* Perform extra checking */
  7. #include <common.h>
  8. #include <errno.h>
  9. #include <asm/io.h>
  10. #include <linux/types.h>
  11. #include <asm/atomic.h>
  12. #include <malloc.h>
  13. #include <asm/arch/soc.h>
  14. #include <fsl-mc/fsl_qbman_base.h>
  15. #define QBMAN_CHECKING
  16. /* Any time there is a register interface which we poll on, this provides a
  17. * "break after x iterations" scheme for it. It's handy for debugging, eg.
  18. * where you don't want millions of lines of log output from a polling loop
  19. * that won't, because such things tend to drown out the earlier log output
  20. * that might explain what caused the problem. (NB: put ";" after each macro!)
  21. * TODO: we should probably remove this once we're done sanitising the
  22. * simulator...
  23. */
  24. #define DBG_POLL_START(loopvar) (loopvar = 10)
  25. #define DBG_POLL_CHECK(loopvar) \
  26. do {if (!(loopvar--)) BUG_ON(NULL == "DBG_POLL_CHECK"); } while (0)
  27. /* For CCSR or portal-CINH registers that contain fields at arbitrary offsets
  28. * and widths, these macro-generated encode/decode/isolate/remove inlines can
  29. * be used.
  30. *
  31. * Eg. to "d"ecode a 14-bit field out of a register (into a "uint16_t" type),
  32. * where the field is located 3 bits "up" from the least-significant bit of the
  33. * register (ie. the field location within the 32-bit register corresponds to a
  34. * mask of 0x0001fff8), you would do;
  35. * uint16_t field = d32_uint16_t(3, 14, reg_value);
  36. *
  37. * Or to "e"ncode a 1-bit boolean value (input type is "int", zero is FALSE,
  38. * non-zero is TRUE, so must convert all non-zero inputs to 1, hence the "!!"
  39. * operator) into a register at bit location 0x00080000 (19 bits "in" from the
  40. * LS bit), do;
  41. * reg_value |= e32_int(19, 1, !!field);
  42. *
  43. * If you wish to read-modify-write a register, such that you leave the 14-bit
  44. * field as-is but have all other fields set to zero, then "i"solate the 14-bit
  45. * value using;
  46. * reg_value = i32_uint16_t(3, 14, reg_value);
  47. *
  48. * Alternatively, you could "r"emove the 1-bit boolean field (setting it to
  49. * zero) but leaving all other fields as-is;
  50. * reg_val = r32_int(19, 1, reg_value);
  51. *
  52. */
  53. #define MAKE_MASK32(width) (width == 32 ? 0xffffffff : \
  54. (uint32_t)((1 << width) - 1))
  55. #define DECLARE_CODEC32(t) \
  56. static inline uint32_t e32_##t(uint32_t lsoffset, uint32_t width, t val) \
  57. { \
  58. BUG_ON(width > (sizeof(t) * 8)); \
  59. return ((uint32_t)val & MAKE_MASK32(width)) << lsoffset; \
  60. } \
  61. static inline t d32_##t(uint32_t lsoffset, uint32_t width, uint32_t val) \
  62. { \
  63. BUG_ON(width > (sizeof(t) * 8)); \
  64. return (t)((val >> lsoffset) & MAKE_MASK32(width)); \
  65. } \
  66. static inline uint32_t i32_##t(uint32_t lsoffset, uint32_t width, \
  67. uint32_t val) \
  68. { \
  69. BUG_ON(width > (sizeof(t) * 8)); \
  70. return e32_##t(lsoffset, width, d32_##t(lsoffset, width, val)); \
  71. } \
  72. static inline uint32_t r32_##t(uint32_t lsoffset, uint32_t width, \
  73. uint32_t val) \
  74. { \
  75. BUG_ON(width > (sizeof(t) * 8)); \
  76. return ~(MAKE_MASK32(width) << lsoffset) & val; \
  77. }
  78. DECLARE_CODEC32(uint32_t)
  79. DECLARE_CODEC32(uint16_t)
  80. DECLARE_CODEC32(uint8_t)
  81. DECLARE_CODEC32(int)
  82. /*********************/
  83. /* Debugging assists */
  84. /*********************/
  85. static inline void __hexdump(unsigned long start, unsigned long end,
  86. unsigned long p, size_t sz, const unsigned char *c)
  87. {
  88. while (start < end) {
  89. unsigned int pos = 0;
  90. char buf[64];
  91. int nl = 0;
  92. pos += sprintf(buf + pos, "%08lx: ", start);
  93. do {
  94. if ((start < p) || (start >= (p + sz)))
  95. pos += sprintf(buf + pos, "..");
  96. else
  97. pos += sprintf(buf + pos, "%02x", *(c++));
  98. if (!(++start & 15)) {
  99. buf[pos++] = '\n';
  100. nl = 1;
  101. } else {
  102. nl = 0;
  103. if (!(start & 1))
  104. buf[pos++] = ' ';
  105. if (!(start & 3))
  106. buf[pos++] = ' ';
  107. }
  108. } while (start & 15);
  109. if (!nl)
  110. buf[pos++] = '\n';
  111. buf[pos] = '\0';
  112. debug("%s", buf);
  113. }
  114. }
  115. static inline void hexdump(const void *ptr, size_t sz)
  116. {
  117. unsigned long p = (unsigned long)ptr;
  118. unsigned long start = p & ~(unsigned long)15;
  119. unsigned long end = (p + sz + 15) & ~(unsigned long)15;
  120. const unsigned char *c = ptr;
  121. __hexdump(start, end, p, sz, c);
  122. }
  123. #if defined(__BIG_ENDIAN)
  124. #define DQRR_TOK_OFFSET 0
  125. #else
  126. #define DQRR_TOK_OFFSET 24
  127. #endif
  128. /* Similarly-named functions */
  129. #define upper32(a) upper_32_bits(a)
  130. #define lower32(a) lower_32_bits(a)
  131. /****************/
  132. /* arch assists */
  133. /****************/
  134. static inline void dcbz(void *ptr)
  135. {
  136. uint32_t *p = ptr;
  137. BUG_ON((unsigned long)ptr & 63);
  138. p[0] = 0;
  139. p[1] = 0;
  140. p[2] = 0;
  141. p[3] = 0;
  142. p[4] = 0;
  143. p[5] = 0;
  144. p[6] = 0;
  145. p[7] = 0;
  146. p[8] = 0;
  147. p[9] = 0;
  148. p[10] = 0;
  149. p[11] = 0;
  150. p[12] = 0;
  151. p[13] = 0;
  152. p[14] = 0;
  153. p[15] = 0;
  154. }
  155. #define lwsync()
  156. void qbman_version(u32 *major, u32 *minor)
  157. {
  158. u32 svr_dev_id;
  159. /*
  160. * LS2080A SoC and its personalities has qbman cotroller version 4.0
  161. * New SoCs like LS2088A, LS1088A has qbman conroller version 4.1
  162. */
  163. svr_dev_id = get_svr();
  164. if (IS_SVR_DEV(svr_dev_id, SVR_DEV(SVR_LS2080A))) {
  165. *major = 4;
  166. *minor = 0;
  167. } else {
  168. *major = 4;
  169. *minor = 1;
  170. }
  171. }
  172. #include "qbman_sys.h"