xref: /openbmc/linux/arch/arc/include/asm/dsp-impl.h (revision ead5d1f4d877e92c051e1a1ade623d0d30e71619)
14827d0cfSEugeniy Paltsev /* SPDX-License-Identifier: GPL-2.0-only */
24827d0cfSEugeniy Paltsev /*
34827d0cfSEugeniy Paltsev  * Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com)
44827d0cfSEugeniy Paltsev  *
54827d0cfSEugeniy Paltsev  * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
64827d0cfSEugeniy Paltsev  */
74827d0cfSEugeniy Paltsev #ifndef __ASM_ARC_DSP_IMPL_H
84827d0cfSEugeniy Paltsev #define __ASM_ARC_DSP_IMPL_H
94827d0cfSEugeniy Paltsev 
107321e2eaSEugeniy Paltsev #include <asm/dsp.h>
117321e2eaSEugeniy Paltsev 
124827d0cfSEugeniy Paltsev #define DSP_CTRL_DISABLED_ALL		0
134827d0cfSEugeniy Paltsev 
144827d0cfSEugeniy Paltsev #ifdef __ASSEMBLY__
154827d0cfSEugeniy Paltsev 
164827d0cfSEugeniy Paltsev /* clobbers r5 register */
174827d0cfSEugeniy Paltsev .macro DSP_EARLY_INIT
18*40db9367SEugeniy Paltsev #ifdef CONFIG_ISA_ARCV2
194827d0cfSEugeniy Paltsev 	lr	r5, [ARC_AUX_DSP_BUILD]
204827d0cfSEugeniy Paltsev 	bmsk	r5, r5, 7
214827d0cfSEugeniy Paltsev 	breq    r5, 0, 1f
224827d0cfSEugeniy Paltsev 	mov	r5, DSP_CTRL_DISABLED_ALL
234827d0cfSEugeniy Paltsev 	sr	r5, [ARC_AUX_DSP_CTRL]
244827d0cfSEugeniy Paltsev 1:
25*40db9367SEugeniy Paltsev #endif
264827d0cfSEugeniy Paltsev .endm
274827d0cfSEugeniy Paltsev 
284827d0cfSEugeniy Paltsev /* clobbers r10, r11 registers pair */
294827d0cfSEugeniy Paltsev .macro DSP_SAVE_REGFILE_IRQ
304827d0cfSEugeniy Paltsev #if defined(CONFIG_ARC_DSP_KERNEL)
314827d0cfSEugeniy Paltsev 	/*
324827d0cfSEugeniy Paltsev 	 * Drop any changes to DSP_CTRL made by userspace so userspace won't be
334827d0cfSEugeniy Paltsev 	 * able to break kernel - reset it to DSP_CTRL_DISABLED_ALL value
344827d0cfSEugeniy Paltsev 	 */
354827d0cfSEugeniy Paltsev 	mov	r10, DSP_CTRL_DISABLED_ALL
364827d0cfSEugeniy Paltsev 	sr	r10, [ARC_AUX_DSP_CTRL]
377321e2eaSEugeniy Paltsev 
387321e2eaSEugeniy Paltsev #elif defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
397321e2eaSEugeniy Paltsev 	/*
407321e2eaSEugeniy Paltsev 	 * Save DSP_CTRL register and reset it to value suitable for kernel
417321e2eaSEugeniy Paltsev 	 * (DSP_CTRL_DISABLED_ALL)
427321e2eaSEugeniy Paltsev 	 */
437321e2eaSEugeniy Paltsev 	mov	r10, DSP_CTRL_DISABLED_ALL
447321e2eaSEugeniy Paltsev 	aex	r10, [ARC_AUX_DSP_CTRL]
457321e2eaSEugeniy Paltsev 	st	r10, [sp, PT_DSP_CTRL]
467321e2eaSEugeniy Paltsev 
477321e2eaSEugeniy Paltsev #endif
487321e2eaSEugeniy Paltsev .endm
497321e2eaSEugeniy Paltsev 
507321e2eaSEugeniy Paltsev /* clobbers r10, r11 registers pair */
517321e2eaSEugeniy Paltsev .macro DSP_RESTORE_REGFILE_IRQ
527321e2eaSEugeniy Paltsev #if defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
537321e2eaSEugeniy Paltsev 	ld	r10, [sp, PT_DSP_CTRL]
547321e2eaSEugeniy Paltsev 	sr	r10, [ARC_AUX_DSP_CTRL]
557321e2eaSEugeniy Paltsev 
567321e2eaSEugeniy Paltsev #endif
574827d0cfSEugeniy Paltsev .endm
584827d0cfSEugeniy Paltsev 
594827d0cfSEugeniy Paltsev #else /* __ASEMBLY__ */
604827d0cfSEugeniy Paltsev 
617321e2eaSEugeniy Paltsev #include <linux/sched.h>
624827d0cfSEugeniy Paltsev #include <asm/asserts.h>
637321e2eaSEugeniy Paltsev #include <asm/switch_to.h>
647321e2eaSEugeniy Paltsev 
657321e2eaSEugeniy Paltsev #ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS
667321e2eaSEugeniy Paltsev 
677321e2eaSEugeniy Paltsev /*
687321e2eaSEugeniy Paltsev  * As we save new and restore old AUX register value in the same place we
697321e2eaSEugeniy Paltsev  * can optimize a bit and use AEX instruction (swap contents of an auxiliary
707321e2eaSEugeniy Paltsev  * register with a core register) instead of LR + SR pair.
717321e2eaSEugeniy Paltsev  */
727321e2eaSEugeniy Paltsev #define AUX_SAVE_RESTORE(_saveto, _readfrom, _offt, _aux)		\
737321e2eaSEugeniy Paltsev do {									\
747321e2eaSEugeniy Paltsev 	long unsigned int _scratch;					\
757321e2eaSEugeniy Paltsev 									\
767321e2eaSEugeniy Paltsev 	__asm__ __volatile__(						\
777321e2eaSEugeniy Paltsev 		"ld	%0, [%2, %4]			\n"		\
787321e2eaSEugeniy Paltsev 		"aex	%0, [%3]			\n"		\
797321e2eaSEugeniy Paltsev 		"st	%0, [%1, %4]			\n"		\
807321e2eaSEugeniy Paltsev 		:							\
817321e2eaSEugeniy Paltsev 		  "=&r" (_scratch)	/* must be early clobber */	\
827321e2eaSEugeniy Paltsev 		:							\
837321e2eaSEugeniy Paltsev 		   "r" (_saveto),					\
847321e2eaSEugeniy Paltsev 		   "r" (_readfrom),					\
857321e2eaSEugeniy Paltsev 		   "Ir" (_aux),						\
867321e2eaSEugeniy Paltsev 		   "Ir" (_offt)						\
877321e2eaSEugeniy Paltsev 		:							\
887321e2eaSEugeniy Paltsev 		  "memory"						\
897321e2eaSEugeniy Paltsev 	);								\
907321e2eaSEugeniy Paltsev } while (0)
917321e2eaSEugeniy Paltsev 
927321e2eaSEugeniy Paltsev #define DSP_AUX_SAVE_RESTORE(_saveto, _readfrom, _aux)			\
937321e2eaSEugeniy Paltsev 	AUX_SAVE_RESTORE(_saveto, _readfrom,				\
947321e2eaSEugeniy Paltsev 		offsetof(struct dsp_callee_regs, _aux),			\
957321e2eaSEugeniy Paltsev 		ARC_AUX_##_aux)
967321e2eaSEugeniy Paltsev 
dsp_save_restore(struct task_struct * prev,struct task_struct * next)977321e2eaSEugeniy Paltsev static inline void dsp_save_restore(struct task_struct *prev,
987321e2eaSEugeniy Paltsev 					struct task_struct *next)
997321e2eaSEugeniy Paltsev {
1007321e2eaSEugeniy Paltsev 	long unsigned int *saveto = &prev->thread.dsp.ACC0_GLO;
1017321e2eaSEugeniy Paltsev 	long unsigned int *readfrom = &next->thread.dsp.ACC0_GLO;
1027321e2eaSEugeniy Paltsev 
1037321e2eaSEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GLO);
1047321e2eaSEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GHI);
1057321e2eaSEugeniy Paltsev 
1067321e2eaSEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_BFLY0);
1077321e2eaSEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_FFT_CTRL);
108f09d3174SEugeniy Paltsev 
109f09d3174SEugeniy Paltsev #ifdef CONFIG_ARC_DSP_AGU_USERSPACE
110f09d3174SEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP0);
111f09d3174SEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP1);
112f09d3174SEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP2);
113f09d3174SEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP3);
114f09d3174SEugeniy Paltsev 
115f09d3174SEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS0);
116f09d3174SEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS1);
117f09d3174SEugeniy Paltsev 
118f09d3174SEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD0);
119f09d3174SEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD1);
120f09d3174SEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD2);
121f09d3174SEugeniy Paltsev 	DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD3);
122f09d3174SEugeniy Paltsev #endif /* CONFIG_ARC_DSP_AGU_USERSPACE */
1237321e2eaSEugeniy Paltsev }
1247321e2eaSEugeniy Paltsev 
1257321e2eaSEugeniy Paltsev #else /* !CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
1267321e2eaSEugeniy Paltsev #define dsp_save_restore(p, n)
1277321e2eaSEugeniy Paltsev #endif /* CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
1284827d0cfSEugeniy Paltsev 
dsp_exist(void)1294827d0cfSEugeniy Paltsev static inline bool dsp_exist(void)
1304827d0cfSEugeniy Paltsev {
1314827d0cfSEugeniy Paltsev 	struct bcr_generic bcr;
1324827d0cfSEugeniy Paltsev 
1334827d0cfSEugeniy Paltsev 	READ_BCR(ARC_AUX_DSP_BUILD, bcr);
1344827d0cfSEugeniy Paltsev 	return !!bcr.ver;
1354827d0cfSEugeniy Paltsev }
1364827d0cfSEugeniy Paltsev 
agu_exist(void)137f09d3174SEugeniy Paltsev static inline bool agu_exist(void)
138f09d3174SEugeniy Paltsev {
139f09d3174SEugeniy Paltsev 	struct bcr_generic bcr;
140f09d3174SEugeniy Paltsev 
141f09d3174SEugeniy Paltsev 	READ_BCR(ARC_AUX_AGU_BUILD, bcr);
142f09d3174SEugeniy Paltsev 	return !!bcr.ver;
143f09d3174SEugeniy Paltsev }
144f09d3174SEugeniy Paltsev 
dsp_config_check(void)1454827d0cfSEugeniy Paltsev static inline void dsp_config_check(void)
1464827d0cfSEugeniy Paltsev {
1474827d0cfSEugeniy Paltsev 	CHK_OPT_STRICT(CONFIG_ARC_DSP_HANDLED, dsp_exist());
148f09d3174SEugeniy Paltsev 	CHK_OPT_WEAK(CONFIG_ARC_DSP_AGU_USERSPACE, agu_exist());
1494827d0cfSEugeniy Paltsev }
1504827d0cfSEugeniy Paltsev 
1514827d0cfSEugeniy Paltsev #endif /* __ASEMBLY__ */
1524827d0cfSEugeniy Paltsev #endif /* __ASM_ARC_DSP_IMPL_H */
153