Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com)
0004  *
0005  * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
0006  */
0007 #ifndef __ASM_ARC_DSP_IMPL_H
0008 #define __ASM_ARC_DSP_IMPL_H
0009 
0010 #include <asm/dsp.h>
0011 
0012 #define DSP_CTRL_DISABLED_ALL       0
0013 
0014 #ifdef __ASSEMBLY__
0015 
0016 /* clobbers r5 register */
0017 .macro DSP_EARLY_INIT
0018 #ifdef CONFIG_ISA_ARCV2
0019     lr  r5, [ARC_AUX_DSP_BUILD]
0020     bmsk    r5, r5, 7
0021     breq    r5, 0, 1f
0022     mov r5, DSP_CTRL_DISABLED_ALL
0023     sr  r5, [ARC_AUX_DSP_CTRL]
0024 1:
0025 #endif
0026 .endm
0027 
0028 /* clobbers r10, r11 registers pair */
0029 .macro DSP_SAVE_REGFILE_IRQ
0030 #if defined(CONFIG_ARC_DSP_KERNEL)
0031     /*
0032      * Drop any changes to DSP_CTRL made by userspace so userspace won't be
0033      * able to break kernel - reset it to DSP_CTRL_DISABLED_ALL value
0034      */
0035     mov r10, DSP_CTRL_DISABLED_ALL
0036     sr  r10, [ARC_AUX_DSP_CTRL]
0037 
0038 #elif defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
0039     /*
0040      * Save DSP_CTRL register and reset it to value suitable for kernel
0041      * (DSP_CTRL_DISABLED_ALL)
0042      */
0043     mov r10, DSP_CTRL_DISABLED_ALL
0044     aex r10, [ARC_AUX_DSP_CTRL]
0045     st  r10, [sp, PT_DSP_CTRL]
0046 
0047 #endif
0048 .endm
0049 
0050 /* clobbers r10, r11 registers pair */
0051 .macro DSP_RESTORE_REGFILE_IRQ
0052 #if defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
0053     ld  r10, [sp, PT_DSP_CTRL]
0054     sr  r10, [ARC_AUX_DSP_CTRL]
0055 
0056 #endif
0057 .endm
0058 
0059 #else /* __ASEMBLY__ */
0060 
0061 #include <linux/sched.h>
0062 #include <asm/asserts.h>
0063 #include <asm/switch_to.h>
0064 
0065 #ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS
0066 
0067 /*
0068  * As we save new and restore old AUX register value in the same place we
0069  * can optimize a bit and use AEX instruction (swap contents of an auxiliary
0070  * register with a core register) instead of LR + SR pair.
0071  */
0072 #define AUX_SAVE_RESTORE(_saveto, _readfrom, _offt, _aux)       \
0073 do {                                    \
0074     long unsigned int _scratch;                 \
0075                                     \
0076     __asm__ __volatile__(                       \
0077         "ld %0, [%2, %4]            \n"     \
0078         "aex    %0, [%3]            \n"     \
0079         "st %0, [%1, %4]            \n"     \
0080         :                           \
0081           "=&r" (_scratch)  /* must be early clobber */ \
0082         :                           \
0083            "r" (_saveto),                   \
0084            "r" (_readfrom),                 \
0085            "Ir" (_aux),                     \
0086            "Ir" (_offt)                     \
0087         :                           \
0088           "memory"                      \
0089     );                              \
0090 } while (0)
0091 
0092 #define DSP_AUX_SAVE_RESTORE(_saveto, _readfrom, _aux)          \
0093     AUX_SAVE_RESTORE(_saveto, _readfrom,                \
0094         offsetof(struct dsp_callee_regs, _aux),         \
0095         ARC_AUX_##_aux)
0096 
0097 static inline void dsp_save_restore(struct task_struct *prev,
0098                     struct task_struct *next)
0099 {
0100     long unsigned int *saveto = &prev->thread.dsp.ACC0_GLO;
0101     long unsigned int *readfrom = &next->thread.dsp.ACC0_GLO;
0102 
0103     DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GLO);
0104     DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GHI);
0105 
0106     DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_BFLY0);
0107     DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_FFT_CTRL);
0108 
0109 #ifdef CONFIG_ARC_DSP_AGU_USERSPACE
0110     DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP0);
0111     DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP1);
0112     DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP2);
0113     DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP3);
0114 
0115     DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS0);
0116     DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS1);
0117 
0118     DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD0);
0119     DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD1);
0120     DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD2);
0121     DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD3);
0122 #endif /* CONFIG_ARC_DSP_AGU_USERSPACE */
0123 }
0124 
0125 #else /* !CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
0126 #define dsp_save_restore(p, n)
0127 #endif /* CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
0128 
0129 static inline bool dsp_exist(void)
0130 {
0131     struct bcr_generic bcr;
0132 
0133     READ_BCR(ARC_AUX_DSP_BUILD, bcr);
0134     return !!bcr.ver;
0135 }
0136 
0137 static inline bool agu_exist(void)
0138 {
0139     struct bcr_generic bcr;
0140 
0141     READ_BCR(ARC_AUX_AGU_BUILD, bcr);
0142     return !!bcr.ver;
0143 }
0144 
0145 static inline void dsp_config_check(void)
0146 {
0147     CHK_OPT_STRICT(CONFIG_ARC_DSP_HANDLED, dsp_exist());
0148     CHK_OPT_WEAK(CONFIG_ARC_DSP_AGU_USERSPACE, agu_exist());
0149 }
0150 
0151 #endif /* __ASEMBLY__ */
0152 #endif /* __ASM_ARC_DSP_IMPL_H */