xrp_dsp_hw_simple.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Copyright (c) 2016 - 2017 Cadence Design Systems Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining
  5. * a copy of this software and associated documentation files (the
  6. * "Software"), to deal in the Software without restriction, including
  7. * without limitation the rights to use, copy, modify, merge, publish,
  8. * distribute, sublicense, and/or sell copies of the Software, and to
  9. * permit persons to whom the Software is furnished to do so, subject to
  10. * the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included
  13. * in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  18. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  19. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  20. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  21. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. #include <stdint.h>
  24. #include <stdio.h>
  25. #include <xtensa/hal.h>
  26. #include <xtensa/xtruntime.h>
  27. #include "xrp_debug.h"
  28. #include "xrp_dsp_hw.h"
  29. #include "xrp_dsp_interrupt.h"
  30. #include "xrp_dsp_sync.h"
  31. #include "xrp_types.h"
  32. #include "xrp_hw_simple_dsp_interface.h"
  33. #include "xrp_rb_file.h"
  34. static uint32_t mmio_base;
  35. static char panic_buffer[4*1024];
  36. static volatile struct xrp_hw_panic *panic = (struct xrp_hw_panic *)panic_buffer;
  37. #define device_mmio(off) ((volatile void *)mmio_base + off)
  38. #define host_mmio(off) ((volatile void *)mmio_base + off)
  39. #define BIT(n) (0x1u<<n)
  40. enum xrp_irq_mode {
  41. XRP_IRQ_NONE,
  42. XRP_IRQ_LEVEL,
  43. XRP_IRQ_EDGE,
  44. };
  45. static enum xrp_irq_mode host_irq_mode;
  46. static enum xrp_irq_mode device_irq_mode;
  47. static uint32_t device_irq_offset;
  48. static uint32_t device_irq_bit;
  49. static uint32_t device_irq;
  50. static uint32_t host_irq_offset;
  51. static uint32_t host_irq_bit;
  52. void hang(void) __attribute__((noreturn));
  53. #if XCHAL_HAVE_INTERRUPTS
  54. void xrp_irq_handler(void)
  55. {
  56. // pr_debug("%s\n", __func__);
  57. if (device_irq_mode == XRP_IRQ_LEVEL)
  58. xrp_s32ri(BIT(device_irq_bit), device_mmio(device_irq_offset));
  59. }
  60. #endif
  61. void xrp_hw_send_host_irq(void)
  62. {
  63. switch (host_irq_mode) {
  64. case XRP_IRQ_EDGE:
  65. xrp_s32ri(0, host_mmio(host_irq_offset));
  66. /* fall through */
  67. case XRP_IRQ_LEVEL:
  68. xrp_s32ri(BIT(host_irq_bit), host_mmio(host_irq_offset));
  69. break;
  70. default:
  71. break;
  72. }
  73. }
  74. uint32_t xrp_hw_is_host_irq_pending(void)
  75. {
  76. switch (host_irq_mode) {
  77. case XRP_IRQ_LEVEL:
  78. return xrp_l32ai(host_mmio(host_irq_offset))& BIT(host_irq_bit);
  79. default:
  80. return 0;
  81. }
  82. }
  83. void xrp_hw_wait_device_irq(void)
  84. {
  85. #if XCHAL_HAVE_INTERRUPTS
  86. unsigned intstate;
  87. if (device_irq_mode == XRP_IRQ_NONE)
  88. return;
  89. pr_debug("%s: waiting for device IRQ...\n", __func__);
  90. #if XCHAL_HAVE_XEA3
  91. intstate = xthal_disable_interrupts();
  92. #else
  93. intstate = XTOS_SET_INTLEVEL(XCHAL_NUM_INTLEVELS - 1);
  94. #endif
  95. xrp_interrupt_enable(device_irq);
  96. XT_WAITI(0);
  97. xrp_interrupt_disable(device_irq);
  98. #if XCHAL_HAVE_XEA3
  99. xthal_restore_interrupts(intstate);
  100. #else
  101. XTOS_RESTORE_INTLEVEL(intstate);
  102. #endif
  103. #endif
  104. }
  105. void xrp_hw_set_sync_data(void *p)
  106. {
  107. static const enum xrp_irq_mode irq_mode[] = {
  108. [XRP_DSP_SYNC_IRQ_MODE_NONE] = XRP_IRQ_NONE,
  109. [XRP_DSP_SYNC_IRQ_MODE_LEVEL] = XRP_IRQ_LEVEL,
  110. [XRP_DSP_SYNC_IRQ_MODE_EDGE] = XRP_IRQ_EDGE,
  111. };
  112. struct xrp_hw_simple_sync_data *hw_sync = p;
  113. // xrp_hw_panic_init(hw_sync->panic_base);
  114. mmio_base = hw_sync->device_mmio_base;
  115. pr_debug("%s: mmio_base: 0x%08x\n", __func__, mmio_base);
  116. if (hw_sync->device_irq_mode < sizeof(irq_mode) / sizeof(*irq_mode)) {
  117. device_irq_mode = irq_mode[hw_sync->device_irq_mode];
  118. device_irq_offset = hw_sync->device_irq_offset;
  119. device_irq_bit = hw_sync->device_irq_bit;
  120. device_irq = hw_sync->device_irq;
  121. pr_debug("%s: device_irq_mode = %d, device_irq_offset = %d, device_irq_bit = %d, device_irq = %d\n",
  122. __func__, device_irq_mode,
  123. device_irq_offset, device_irq_bit, device_irq);
  124. } else {
  125. device_irq_mode = XRP_IRQ_NONE;
  126. }
  127. if (hw_sync->host_irq_mode < sizeof(irq_mode) / sizeof(*irq_mode)) {
  128. host_irq_mode = irq_mode[hw_sync->host_irq_mode];
  129. host_irq_offset = hw_sync->host_irq_offset;
  130. host_irq_bit = hw_sync->host_irq_bit;
  131. pr_debug("%s: host_irq_mode = %d, host_irq_offset = %d, host_irq_bit = %d\n",
  132. __func__, host_irq_mode, host_irq_offset, host_irq_bit);
  133. } else {
  134. host_irq_mode = XRP_IRQ_NONE;
  135. }
  136. if (device_irq_mode != XRP_IRQ_NONE) {
  137. #if XCHAL_HAVE_INTERRUPTS
  138. #if XCHAL_HAVE_XEA3
  139. xthal_interrupt_sens_set(device_irq,
  140. device_irq_mode == XRP_IRQ_LEVEL);
  141. #endif
  142. xrp_interrupt_disable(device_irq);
  143. xrp_set_interrupt_handler(device_irq, xrp_irq_handler);
  144. #endif
  145. }
  146. }
  147. int xrp_get_irq()
  148. {
  149. return device_irq;
  150. }
  151. void xrp_interrupt_on()
  152. {
  153. xrp_interrupt_enable(device_irq);
  154. }
  155. void xrp_interrupt_off()
  156. {
  157. xrp_interrupt_disable(device_irq);
  158. }
  159. void xrp_hw_panic(void)
  160. {
  161. if(panic)
  162. {
  163. panic->panic = 0xdeadbabe;
  164. panic->ccount = XT_RSR_CCOUNT();
  165. }
  166. }
  167. void hang(void)
  168. {
  169. for (;;)
  170. xrp_hw_panic();
  171. }
  172. int xrp_hw_panic_init(void * base)
  173. {
  174. if(base == NULL)
  175. {
  176. return -1;
  177. }
  178. else
  179. {
  180. panic = base;
  181. }
  182. return 0;
  183. }
  184. void xrp_hw_init()
  185. {
  186. }
  187. void board_init(void)
  188. {
  189. /* Nothing. */
  190. }
  191. void outbyte(int c)
  192. {
  193. char b = (unsigned char)c;
  194. if(panic)
  195. xrp_rb_write((void *)&panic->rb, &b, 1);
  196. }
  197. int inbyte(void)
  198. {
  199. return -1;
  200. }