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