ARC: allow userspace DSP applications to use AGU extensions

To be able to run DSP-enabled userspace applications with AGU
(address generation unit) extensions we additionally need to
save and restore following registers at context switch:
 * AGU_AP*
 * AGU_OS*
 * AGU_MOD*

Reviewed-by: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
This commit is contained in:
Eugeniy Paltsev 2020-03-05 23:02:52 +03:00 committed by Vineet Gupta
parent 7321e2ea0d
commit f09d3174f0
6 changed files with 66 additions and 0 deletions

View File

@ -445,6 +445,15 @@ config ARC_DSP_USERSPACE
help
DSP extension presence in HW, support save / restore DSP registers to
run DSP-enabled userspace applications
config ARC_DSP_AGU_USERSPACE
bool "Support DSP with AGU for userspace apps"
select ARC_HAS_ACCL_REGS
select ARC_DSP_HANDLED
select ARC_DSP_SAVE_RESTORE_REGS
help
DSP and AGU extensions presence in HW, support save / restore DSP
and AGU registers to run DSP-enabled userspace applications
endchoice
config ARC_IRQ_NO_AUTOSAVE

View File

@ -132,6 +132,18 @@
#define ARC_AUX_DSP_CTRL 0x59F
#define ARC_AUX_DSP_FFT_CTRL 0x59E
#define ARC_AUX_AGU_BUILD 0xCC
#define ARC_AUX_AGU_AP0 0x5C0
#define ARC_AUX_AGU_AP1 0x5C1
#define ARC_AUX_AGU_AP2 0x5C2
#define ARC_AUX_AGU_AP3 0x5C3
#define ARC_AUX_AGU_OS0 0x5D0
#define ARC_AUX_AGU_OS1 0x5D1
#define ARC_AUX_AGU_MOD0 0x5E0
#define ARC_AUX_AGU_MOD1 0x5E1
#define ARC_AUX_AGU_MOD2 0x5E2
#define ARC_AUX_AGU_MOD3 0x5E3
#ifndef __ASSEMBLY__
#include <soc/arc/aux.h>

View File

@ -10,6 +10,7 @@
/* Helpers to sanitize config options. */
void chk_opt_strict(char *opt_name, bool hw_exists, bool opt_ena);
void chk_opt_weak(char *opt_name, bool hw_exists, bool opt_ena);
/*
* Check required config option:
@ -21,4 +22,13 @@ void chk_opt_strict(char *opt_name, bool hw_exists, bool opt_ena);
chk_opt_strict(#opt_name, hw_exists, IS_ENABLED(opt_name)); \
})
/*
* Check optional config option:
* - panic in case of OPT enabled but corresponding HW absent.
*/
#define CHK_OPT_WEAK(opt_name, hw_exists) \
({ \
chk_opt_weak(#opt_name, hw_exists, IS_ENABLED(opt_name)); \
})
#endif /* __ASM_ARC_ASSERTS_H */

View File

@ -103,6 +103,21 @@ static inline void dsp_save_restore(struct task_struct *prev,
DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_BFLY0);
DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_FFT_CTRL);
#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 */
}
#else /* !CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
@ -117,9 +132,18 @@ static inline bool dsp_exist(void)
return !!bcr.ver;
}
static inline bool agu_exist(void)
{
struct bcr_generic bcr;
READ_BCR(ARC_AUX_AGU_BUILD, bcr);
return !!bcr.ver;
}
static inline void dsp_config_check(void)
{
CHK_OPT_STRICT(CONFIG_ARC_DSP_HANDLED, dsp_exist());
CHK_OPT_WEAK(CONFIG_ARC_DSP_AGU_USERSPACE, agu_exist());
}
#endif /* __ASEMBLY__ */

View File

@ -17,6 +17,11 @@
*/
struct dsp_callee_regs {
unsigned long ACC0_GLO, ACC0_GHI, DSP_BFLY0, DSP_FFT_CTRL;
#ifdef CONFIG_ARC_DSP_AGU_USERSPACE
unsigned long AGU_AP0, AGU_AP1, AGU_AP2, AGU_AP3;
unsigned long AGU_OS0, AGU_OS1;
unsigned long AGU_MOD0, AGU_MOD1, AGU_MOD2, AGU_MOD3;
#endif
};
#endif /* !__ASSEMBLY__ */

View File

@ -399,6 +399,12 @@ void chk_opt_strict(char *opt_name, bool hw_exists, bool opt_ena)
panic("Disable %s, hardware NOT present\n", opt_name);
}
void chk_opt_weak(char *opt_name, bool hw_exists, bool opt_ena)
{
if (!hw_exists && opt_ena)
panic("Disable %s, hardware NOT present\n", opt_name);
}
static void arc_chk_core_config(void)
{
struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];