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 #ifdef CONFIG_ISA_ARCV2
19 lr r5
, [ARC_AUX_DSP_BUILD
]
22 mov r5
, DSP_CTRL_DISABLED_ALL
23 sr r5
, [ARC_AUX_DSP_CTRL
]
28 /* clobbers r10, r11 registers pair */
29 .macro DSP_SAVE_REGFILE_IRQ
30 #if defined(CONFIG_ARC_DSP_KERNEL)
32 * Drop any changes to DSP_CTRL made by userspace so userspace won't be
33 * able to break kernel - reset it to DSP_CTRL_DISABLED_ALL value
35 mov r10
, DSP_CTRL_DISABLED_ALL
36 sr r10
, [ARC_AUX_DSP_CTRL
]
38 #elif defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
40 * Save DSP_CTRL register and reset it to value suitable for kernel
41 * (DSP_CTRL_DISABLED_ALL)
43 mov r10
, DSP_CTRL_DISABLED_ALL
44 aex r10
, [ARC_AUX_DSP_CTRL
]
45 st r10
, [sp
, PT_DSP_CTRL
]
50 /* clobbers r10, r11 registers pair */
51 .macro DSP_RESTORE_REGFILE_IRQ
52 #if defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
53 ld r10
, [sp
, PT_DSP_CTRL
]
54 sr r10
, [ARC_AUX_DSP_CTRL
]
59 #else /* __ASEMBLY__ */
61 #include <linux/sched.h>
62 #include <asm/asserts.h>
63 #include <asm/switch_to.h>
65 #ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS
68 * As we save new and restore old AUX register value in the same place we
69 * can optimize a bit and use AEX instruction (swap contents of an auxiliary
70 * register with a core register) instead of LR + SR pair.
72 #define AUX_SAVE_RESTORE(_saveto, _readfrom, _offt, _aux) \
74 long unsigned int _scratch; \
76 __asm__ __volatile__( \
77 "ld %0, [%2, %4] \n" \
79 "st %0, [%1, %4] \n" \
81 "=&r" (_scratch) /* must be early clobber */ \
92 #define DSP_AUX_SAVE_RESTORE(_saveto, _readfrom, _aux) \
93 AUX_SAVE_RESTORE(_saveto, _readfrom, \
94 offsetof(struct dsp_callee_regs, _aux), \
97 static inline void dsp_save_restore(struct task_struct
*prev
,
98 struct task_struct
*next
)
100 long unsigned int *saveto
= &prev
->thread
.dsp
.ACC0_GLO
;
101 long unsigned int *readfrom
= &next
->thread
.dsp
.ACC0_GLO
;
103 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, ACC0_GLO
);
104 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, ACC0_GHI
);
106 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, DSP_BFLY0
);
107 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, DSP_FFT_CTRL
);
109 #ifdef CONFIG_ARC_DSP_AGU_USERSPACE
110 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, AGU_AP0
);
111 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, AGU_AP1
);
112 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, AGU_AP2
);
113 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, AGU_AP3
);
115 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, AGU_OS0
);
116 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, AGU_OS1
);
118 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, AGU_MOD0
);
119 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, AGU_MOD1
);
120 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, AGU_MOD2
);
121 DSP_AUX_SAVE_RESTORE(saveto
, readfrom
, AGU_MOD3
);
122 #endif /* CONFIG_ARC_DSP_AGU_USERSPACE */
125 #else /* !CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
126 #define dsp_save_restore(p, n)
127 #endif /* CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
129 static inline bool dsp_exist(void)
131 struct bcr_generic bcr
;
133 READ_BCR(ARC_AUX_DSP_BUILD
, bcr
);
137 static inline bool agu_exist(void)
139 struct bcr_generic bcr
;
141 READ_BCR(ARC_AUX_AGU_BUILD
, bcr
);
145 static inline void dsp_config_check(void)
147 CHK_OPT_STRICT(CONFIG_ARC_DSP_HANDLED
, dsp_exist());
148 CHK_OPT_WEAK(CONFIG_ARC_DSP_AGU_USERSPACE
, agu_exist());
151 #endif /* __ASEMBLY__ */
152 #endif /* __ASM_ARC_DSP_IMPL_H */