ARC: allow userspace DSP applications to use AGU extensions
authorEugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
Thu, 5 Mar 2020 20:02:52 +0000 (23:02 +0300)
committerVineet Gupta <vgupta@synopsys.com>
Mon, 16 Mar 2020 17:30:49 +0000 (10:30 -0700)
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>
arch/arc/Kconfig
arch/arc/include/asm/arcregs.h
arch/arc/include/asm/asserts.h
arch/arc/include/asm/dsp-impl.h
arch/arc/include/asm/dsp.h
arch/arc/kernel/setup.c

index eb3bcb206882472f6c629abdfb96ba3aa36f0b71..ff306246d0f80717c1951082be54d5433eda6210 100644 (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
index aee1ee2630658f6f0480d99c02865855b50c763a..2162023195c5aacb61a38301601f0d6da9c31e11 100644 (file)
 #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>
index 3314efbeb52886488e42f2dc8f91e03941489207..108f33be6aa5469a0f30e97a77a47bf4ad9a0668 100644 (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 */
index 8380f7bede81198fdb3a22b0174cb0e0f43462f6..e1aa212ca6ebd1203e34dfc0c0f310af47964f77 100644 (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__ */
index b016f4d2a09fdd9bf6b463498999353c6670bf1b..202c78e567045bdc442c62f4a23c5b382a6d5b80 100644 (file)
  */
 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__ */
index 1ed1528d9045a5db231cc11b86a1a3f93812368c..b2b1cb645d9e90c4d41cb7e03226eee1fe361a88 100644 (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()];