2020-03-05 23:02:50 +03:00
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright ( C ) 2020 Synopsys , Inc . ( www . synopsys . com )
*
* Author : Eugeniy Paltsev < Eugeniy . Paltsev @ synopsys . com >
*/
# ifndef __ASM_ARC_DSP_IMPL_H
# define __ASM_ARC_DSP_IMPL_H
2020-03-05 23:02:51 +03:00
# include <asm/dsp.h>
2020-03-05 23:02:50 +03:00
# define DSP_CTRL_DISABLED_ALL 0
# ifdef __ASSEMBLY__
/* clobbers r5 register */
. macro DSP_EARLY_INIT
2020-04-28 21:50:24 +03:00
# ifdef CONFIG_ISA_ARCV2
2020-03-05 23:02:50 +03:00
lr r5 , [ ARC_AUX_DSP_BUILD ]
bmsk r5 , r5 , 7
breq r5 , 0 , 1f
mov r5 , DSP_CTRL_DISABLED_ALL
sr r5 , [ ARC_AUX_DSP_CTRL ]
1 :
2020-04-28 21:50:24 +03:00
# endif
2020-03-05 23:02:50 +03:00
. endm
/* clobbers r10, r11 registers pair */
. macro DSP_SAVE_REGFILE_IRQ
# if defined(CONFIG_ARC_DSP_KERNEL)
/*
* Drop any changes to DSP_CTRL made by userspace so userspace won ' t be
* able to break kernel - reset it to DSP_CTRL_DISABLED_ALL value
*/
mov r10 , DSP_CTRL_DISABLED_ALL
sr r10 , [ ARC_AUX_DSP_CTRL ]
2020-03-05 23:02:51 +03:00
# elif defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
/*
* Save DSP_CTRL register and reset it to value suitable for kernel
* ( DSP_CTRL_DISABLED_ALL )
*/
mov r10 , DSP_CTRL_DISABLED_ALL
aex r10 , [ ARC_AUX_DSP_CTRL ]
st r10 , [ sp , PT_DSP_CTRL ]
# endif
. endm
/* clobbers r10, r11 registers pair */
. macro DSP_RESTORE_REGFILE_IRQ
# if defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
ld r10 , [ sp , PT_DSP_CTRL ]
sr r10 , [ ARC_AUX_DSP_CTRL ]
# endif
2020-03-05 23:02:50 +03:00
. endm
# else /* __ASEMBLY__ */
2020-03-05 23:02:51 +03:00
# include <linux/sched.h>
2020-03-05 23:02:50 +03:00
# include <asm/asserts.h>
2020-03-05 23:02:51 +03:00
# include <asm/switch_to.h>
# ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS
/*
* As we save new and restore old AUX register value in the same place we
* can optimize a bit and use AEX instruction ( swap contents of an auxiliary
* register with a core register ) instead of LR + SR pair .
*/
# define AUX_SAVE_RESTORE(_saveto, _readfrom, _offt, _aux) \
do { \
long unsigned int _scratch ; \
\
__asm__ __volatile__ ( \
" ld %0, [%2, %4] \n " \
" aex %0, [%3] \n " \
" st %0, [%1, %4] \n " \
: \
" =&r " ( _scratch ) /* must be early clobber */ \
: \
" r " ( _saveto ) , \
" r " ( _readfrom ) , \
" Ir " ( _aux ) , \
" Ir " ( _offt ) \
: \
" memory " \
) ; \
} while ( 0 )
# define DSP_AUX_SAVE_RESTORE(_saveto, _readfrom, _aux) \
AUX_SAVE_RESTORE ( _saveto , _readfrom , \
offsetof ( struct dsp_callee_regs , _aux ) , \
ARC_AUX_ # # _aux )
static inline void dsp_save_restore ( struct task_struct * prev ,
struct task_struct * next )
{
long unsigned int * saveto = & prev - > thread . dsp . ACC0_GLO ;
long unsigned int * readfrom = & next - > thread . dsp . ACC0_GLO ;
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , ACC0_GLO ) ;
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , ACC0_GHI ) ;
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , DSP_BFLY0 ) ;
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , DSP_FFT_CTRL ) ;
2020-03-05 23:02:52 +03:00
# ifdef CONFIG_ARC_DSP_AGU_USERSPACE
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , AGU_AP0 ) ;
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , AGU_AP1 ) ;
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , AGU_AP2 ) ;
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , AGU_AP3 ) ;
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , AGU_OS0 ) ;
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , AGU_OS1 ) ;
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , AGU_MOD0 ) ;
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , AGU_MOD1 ) ;
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , AGU_MOD2 ) ;
DSP_AUX_SAVE_RESTORE ( saveto , readfrom , AGU_MOD3 ) ;
# endif /* CONFIG_ARC_DSP_AGU_USERSPACE */
2020-03-05 23:02:51 +03:00
}
# else /* !CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
# define dsp_save_restore(p, n)
# endif /* CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
2020-03-05 23:02:50 +03:00
static inline bool dsp_exist ( void )
{
struct bcr_generic bcr ;
READ_BCR ( ARC_AUX_DSP_BUILD , bcr ) ;
return ! ! bcr . ver ;
}
2020-03-05 23:02:52 +03:00
static inline bool agu_exist ( void )
{
struct bcr_generic bcr ;
READ_BCR ( ARC_AUX_AGU_BUILD , bcr ) ;
return ! ! bcr . ver ;
}
2020-03-05 23:02:50 +03:00
static inline void dsp_config_check ( void )
{
CHK_OPT_STRICT ( CONFIG_ARC_DSP_HANDLED , dsp_exist ( ) ) ;
2020-03-05 23:02:52 +03:00
CHK_OPT_WEAK ( CONFIG_ARC_DSP_AGU_USERSPACE , agu_exist ( ) ) ;
2020-03-05 23:02:50 +03:00
}
# endif /* __ASEMBLY__ */
# endif /* __ASM_ARC_DSP_IMPL_H */