Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/arc/include/asm/dsp-impl.h
26481 views
1
/* SPDX-License-Identifier: GPL-2.0-only */
2
/*
3
* Copyright (C) 2020 Synopsys, Inc. (www.synopsys.com)
4
*
5
* Author: Eugeniy Paltsev <[email protected]>
6
*/
7
#ifndef __ASM_ARC_DSP_IMPL_H
8
#define __ASM_ARC_DSP_IMPL_H
9
10
#include <asm/dsp.h>
11
12
#define DSP_CTRL_DISABLED_ALL 0
13
14
#ifdef __ASSEMBLER__
15
16
/* clobbers r5 register */
17
.macro DSP_EARLY_INIT
18
#ifdef CONFIG_ISA_ARCV2
19
lr r5, [ARC_AUX_DSP_BUILD]
20
bmsk r5, r5, 7
21
breq r5, 0, 1f
22
mov r5, DSP_CTRL_DISABLED_ALL
23
sr r5, [ARC_AUX_DSP_CTRL]
24
1:
25
#endif
26
.endm
27
28
/* clobbers r10, r11 registers pair */
29
.macro DSP_SAVE_REGFILE_IRQ
30
#if defined(CONFIG_ARC_DSP_KERNEL)
31
/*
32
* Drop any changes to DSP_CTRL made by userspace so userspace won't be
33
* able to break kernel - reset it to DSP_CTRL_DISABLED_ALL value
34
*/
35
mov r10, DSP_CTRL_DISABLED_ALL
36
sr r10, [ARC_AUX_DSP_CTRL]
37
38
#elif defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
39
/*
40
* Save DSP_CTRL register and reset it to value suitable for kernel
41
* (DSP_CTRL_DISABLED_ALL)
42
*/
43
mov r10, DSP_CTRL_DISABLED_ALL
44
aex r10, [ARC_AUX_DSP_CTRL]
45
st r10, [sp, PT_DSP_CTRL]
46
47
#endif
48
.endm
49
50
/* clobbers r10, r11 registers pair */
51
.macro DSP_RESTORE_REGFILE_IRQ
52
#if defined(CONFIG_ARC_DSP_SAVE_RESTORE_REGS)
53
ld r10, [sp, PT_DSP_CTRL]
54
sr r10, [ARC_AUX_DSP_CTRL]
55
56
#endif
57
.endm
58
59
#else /* __ASEMBLY__ */
60
61
#include <linux/sched.h>
62
#include <asm/asserts.h>
63
#include <asm/switch_to.h>
64
65
#ifdef CONFIG_ARC_DSP_SAVE_RESTORE_REGS
66
67
/*
68
* As we save new and restore old AUX register value in the same place we
69
* can optimize a bit and use AEX instruction (swap contents of an auxiliary
70
* register with a core register) instead of LR + SR pair.
71
*/
72
#define AUX_SAVE_RESTORE(_saveto, _readfrom, _offt, _aux) \
73
do { \
74
long unsigned int _scratch; \
75
\
76
__asm__ __volatile__( \
77
"ld %0, [%2, %4] \n" \
78
"aex %0, [%3] \n" \
79
"st %0, [%1, %4] \n" \
80
: \
81
"=&r" (_scratch) /* must be early clobber */ \
82
: \
83
"r" (_saveto), \
84
"r" (_readfrom), \
85
"Ir" (_aux), \
86
"Ir" (_offt) \
87
: \
88
"memory" \
89
); \
90
} while (0)
91
92
#define DSP_AUX_SAVE_RESTORE(_saveto, _readfrom, _aux) \
93
AUX_SAVE_RESTORE(_saveto, _readfrom, \
94
offsetof(struct dsp_callee_regs, _aux), \
95
ARC_AUX_##_aux)
96
97
static inline void dsp_save_restore(struct task_struct *prev,
98
struct task_struct *next)
99
{
100
long unsigned int *saveto = &prev->thread.dsp.ACC0_GLO;
101
long unsigned int *readfrom = &next->thread.dsp.ACC0_GLO;
102
103
DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GLO);
104
DSP_AUX_SAVE_RESTORE(saveto, readfrom, ACC0_GHI);
105
106
DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_BFLY0);
107
DSP_AUX_SAVE_RESTORE(saveto, readfrom, DSP_FFT_CTRL);
108
109
#ifdef CONFIG_ARC_DSP_AGU_USERSPACE
110
DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP0);
111
DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP1);
112
DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP2);
113
DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_AP3);
114
115
DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS0);
116
DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_OS1);
117
118
DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD0);
119
DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD1);
120
DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD2);
121
DSP_AUX_SAVE_RESTORE(saveto, readfrom, AGU_MOD3);
122
#endif /* CONFIG_ARC_DSP_AGU_USERSPACE */
123
}
124
125
#else /* !CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
126
#define dsp_save_restore(p, n)
127
#endif /* CONFIG_ARC_DSP_SAVE_RESTORE_REGS */
128
129
static inline bool dsp_exist(void)
130
{
131
struct bcr_generic bcr;
132
133
READ_BCR(ARC_AUX_DSP_BUILD, bcr);
134
return !!bcr.ver;
135
}
136
137
static inline bool agu_exist(void)
138
{
139
struct bcr_generic bcr;
140
141
READ_BCR(ARC_AUX_AGU_BUILD, bcr);
142
return !!bcr.ver;
143
}
144
145
static inline void dsp_config_check(void)
146
{
147
CHK_OPT_STRICT(CONFIG_ARC_DSP_HANDLED, dsp_exist());
148
CHK_OPT_WEAK(CONFIG_ARC_DSP_AGU_USERSPACE, agu_exist());
149
}
150
151
#endif /* __ASEMBLY__ */
152
#endif /* __ASM_ARC_DSP_IMPL_H */
153
154