1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com)
5 * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
7 #ifndef __ASM_ARC_DSP_IMPL_H
8 #define __ASM_ARC_DSP_IMPL_H
12 #define DSP_CTRL_DISABLED_ALL 0
16 /* clobbers r5 register */
18 lr r5, [ARC_AUX_DSP_BUILD]
21 mov r5, DSP_CTRL_DISABLED_ALL
22 sr r5, [ARC_AUX_DSP_CTRL]
26 /* clobbers r10, r11 registers pair */
27 .macro DSP_SAVE_REGFILE_IRQ
28 #if defined(CONFIG_ARC_DSP_KERNEL)
30 * Drop any changes to DSP_CTRL made by userspace so userspace won't be
31 * able to break kernel - reset it to DSP_CTRL_DISABLED_ALL value
33 mov r10, DSP_CTRL_DISABLED_ALL
34 sr r10, [ARC_AUX_DSP_CTRL]
36 #elif defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
38 * Save DSP_CTRL register and reset it to value suitable for kernel
39 * (DSP_CTRL_DISABLED_ALL)
41 mov r10, DSP_CTRL_DISABLED_ALL
42 aex r10, [ARC_AUX_DSP_CTRL]
43 st r10, [sp, PT_DSP_CTRL]
48 /* clobbers r10, r11 registers pair */
49 .macro DSP_RESTORE_REGFILE_IRQ
50 #if defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
51 ld r10, [sp, PT_DSP_CTRL]
52 sr r10, [ARC_AUX_DSP_CTRL]
57 #else /* __ASEMBLY__ */
59 #include <linux/sched.h>
60 #include <asm/asserts.h>
61 #include <asm/switch_to.h>
63 #ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS
66 * As we save new and restore old AUX register value in the same place we
67 * can optimize a bit and use AEX instruction (swap contents of an auxiliary
68 * register with a core register) instead of LR + SR pair.
70 #define AUX_SAVE_RESTORE(_saveto, _readfrom, _offt, _aux) \
72 long unsigned int _scratch; \
74 __asm__ __volatile__( \
75 "ld %0, [%2, %4] \n" \
77 "st %0, [%1, %4] \n" \
79 "=&r" (_scratch) /* must be early clobber */ \
90 #define DSP_AUX_SAVE_RESTORE(_saveto, _readfrom, _aux) \
91 AUX_SAVE_RESTORE(_saveto, _readfrom, \
92 offsetof(struct dsp_callee_regs, _aux), \
95 static inline void dsp_save_restore(struct task_struct *prev,
96 struct task_struct *next)
98 long unsigned int *saveto = &prev->thread.dsp.ACC0_GLO;
99 long unsigned int *readfrom = &next->thread.dsp.ACC0_GLO;
101 DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GLO);
102 DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GHI);
104 DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_BFLY0);
105 DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_FFT_CTRL);
108 #else /* !CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
109 #define dsp_save_restore(p, n)
110 #endif /* CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
112 static inline bool dsp_exist(void)
114 struct bcr_generic bcr;
116 READ_BCR(ARC_AUX_DSP_BUILD, bcr);
120 static inline void dsp_config_check(void)
122 CHK_OPT_STRICT(CONFIG_ARC_DSP_HANDLED, dsp_exist());
125 #endif /* __ASEMBLY__ */
126 #endif /* __ASM_ARC_DSP_IMPL_H */