dsp-impl.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com)
  4. *
  5. * Author: Eugeniy Paltsev <[email protected]>
  6. */
  7. #ifndef __ASM_ARC_DSP_IMPL_H
  8. #define __ASM_ARC_DSP_IMPL_H
  9. #include <asm/dsp.h>
  10. #define DSP_CTRL_DISABLED_ALL 0
  11. #ifdef __ASSEMBLY__
  12. /* clobbers r5 register */
  13. .macro DSP_EARLY_INIT
  14. #ifdef CONFIG_ISA_ARCV2
  15. lr r5, [ARC_AUX_DSP_BUILD]
  16. bmsk r5, r5, 7
  17. breq r5, 0, 1f
  18. mov r5, DSP_CTRL_DISABLED_ALL
  19. sr r5, [ARC_AUX_DSP_CTRL]
  20. 1:
  21. #endif
  22. .endm
  23. /* clobbers r10, r11 registers pair */
  24. .macro DSP_SAVE_REGFILE_IRQ
  25. #if defined(CONFIG_ARC_DSP_KERNEL)
  26. /*
  27. * Drop any changes to DSP_CTRL made by userspace so userspace won't be
  28. * able to break kernel - reset it to DSP_CTRL_DISABLED_ALL value
  29. */
  30. mov r10, DSP_CTRL_DISABLED_ALL
  31. sr r10, [ARC_AUX_DSP_CTRL]
  32. #elif defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
  33. /*
  34. * Save DSP_CTRL register and reset it to value suitable for kernel
  35. * (DSP_CTRL_DISABLED_ALL)
  36. */
  37. mov r10, DSP_CTRL_DISABLED_ALL
  38. aex r10, [ARC_AUX_DSP_CTRL]
  39. st r10, [sp, PT_DSP_CTRL]
  40. #endif
  41. .endm
  42. /* clobbers r10, r11 registers pair */
  43. .macro DSP_RESTORE_REGFILE_IRQ
  44. #if defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
  45. ld r10, [sp, PT_DSP_CTRL]
  46. sr r10, [ARC_AUX_DSP_CTRL]
  47. #endif
  48. .endm
  49. #else /* __ASEMBLY__ */
  50. #include <linux/sched.h>
  51. #include <asm/asserts.h>
  52. #include <asm/switch_to.h>
  53. #ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS
  54. /*
  55. * As we save new and restore old AUX register value in the same place we
  56. * can optimize a bit and use AEX instruction (swap contents of an auxiliary
  57. * register with a core register) instead of LR + SR pair.
  58. */
  59. #define AUX_SAVE_RESTORE(_saveto, _readfrom, _offt, _aux) \
  60. do { \
  61. long unsigned int _scratch; \
  62. \
  63. __asm__ __volatile__( \
  64. "ld %0, [%2, %4] \n" \
  65. "aex %0, [%3] \n" \
  66. "st %0, [%1, %4] \n" \
  67. : \
  68. "=&r" (_scratch) /* must be early clobber */ \
  69. : \
  70. "r" (_saveto), \
  71. "r" (_readfrom), \
  72. "Ir" (_aux), \
  73. "Ir" (_offt) \
  74. : \
  75. "memory" \
  76. ); \
  77. } while (0)
  78. #define DSP_AUX_SAVE_RESTORE(_saveto, _readfrom, _aux) \
  79. AUX_SAVE_RESTORE(_saveto, _readfrom, \
  80. offsetof(struct dsp_callee_regs, _aux), \
  81. ARC_AUX_##_aux)
  82. static inline void dsp_save_restore(struct task_struct *prev,
  83. struct task_struct *next)
  84. {
  85. long unsigned int *saveto = &prev->thread.dsp.ACC0_GLO;
  86. long unsigned int *readfrom = &next->thread.dsp.ACC0_GLO;
  87. DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GLO);
  88. DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GHI);
  89. DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_BFLY0);
  90. DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_FFT_CTRL);
  91. #ifdef CONFIG_ARC_DSP_AGU_USERSPACE
  92. DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP0);
  93. DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP1);
  94. DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP2);
  95. DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP3);
  96. DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS0);
  97. DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS1);
  98. DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD0);
  99. DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD1);
  100. DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD2);
  101. DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD3);
  102. #endif /* CONFIG_ARC_DSP_AGU_USERSPACE */
  103. }
  104. #else /* !CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
  105. #define dsp_save_restore(p, n)
  106. #endif /* CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
  107. static inline bool dsp_exist(void)
  108. {
  109. struct bcr_generic bcr;
  110. READ_BCR(ARC_AUX_DSP_BUILD, bcr);
  111. return !!bcr.ver;
  112. }
  113. static inline bool agu_exist(void)
  114. {
  115. struct bcr_generic bcr;
  116. READ_BCR(ARC_AUX_AGU_BUILD, bcr);
  117. return !!bcr.ver;
  118. }
  119. static inline void dsp_config_check(void)
  120. {
  121. CHK_OPT_STRICT(CONFIG_ARC_DSP_HANDLED, dsp_exist());
  122. CHK_OPT_WEAK(CONFIG_ARC_DSP_AGU_USERSPACE, agu_exist());
  123. }
  124. #endif /* __ASEMBLY__ */
  125. #endif /* __ASM_ARC_DSP_IMPL_H */