aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinod Koul <vinod.koul@intel.com>2013-01-21 09:35:12 -0500
committerVinod Koul <vinod.koul@intel.com>2013-01-21 10:09:34 -0500
commit6c5e6a3990ce64192b56ffafa5ffa5af129751d5 (patch)
tree228632cd25a3ce0e00194fb492eaa4c50e5acbae
parent77bcc497c60ec62dbb84abc809a6e218d53409e9 (diff)
parentda2ac56a1bc9c6c56244aa9ca990d5c5c7574b5f (diff)
Merge tag 'ux500-dma40' of //git.linaro.org/people/fabiobaltieri/linux.git
Pull ste_dma40 fixes from Fabio Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-rw-r--r--drivers/dma/ste_dma40.c489
-rw-r--r--drivers/dma/ste_dma40_ll.c29
-rw-r--r--drivers/dma/ste_dma40_ll.h130
-rw-r--r--include/linux/platform_data/dma-ste-dma40.h13
4 files changed, 518 insertions, 143 deletions
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index e5e60bb68d9d..ad860a221c33 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -53,6 +53,8 @@
53#define D40_ALLOC_PHY (1 << 30) 53#define D40_ALLOC_PHY (1 << 30)
54#define D40_ALLOC_LOG_FREE 0 54#define D40_ALLOC_LOG_FREE 0
55 55
56#define MAX(a, b) (((a) < (b)) ? (b) : (a))
57
56/** 58/**
57 * enum 40_command - The different commands and/or statuses. 59 * enum 40_command - The different commands and/or statuses.
58 * 60 *
@@ -100,8 +102,19 @@ static u32 d40_backup_regs[] = {
100 102
101#define BACKUP_REGS_SZ ARRAY_SIZE(d40_backup_regs) 103#define BACKUP_REGS_SZ ARRAY_SIZE(d40_backup_regs)
102 104
103/* TODO: Check if all these registers have to be saved/restored on dma40 v3 */ 105/*
104static u32 d40_backup_regs_v3[] = { 106 * since 9540 and 8540 has the same HW revision
107 * use v4a for 9540 or ealier
108 * use v4b for 8540 or later
109 * HW revision:
110 * DB8500ed has revision 0
111 * DB8500v1 has revision 2
112 * DB8500v2 has revision 3
113 * AP9540v1 has revision 4
114 * DB8540v1 has revision 4
115 * TODO: Check if all these registers have to be saved/restored on dma40 v4a
116 */
117static u32 d40_backup_regs_v4a[] = {
105 D40_DREG_PSEG1, 118 D40_DREG_PSEG1,
106 D40_DREG_PSEG2, 119 D40_DREG_PSEG2,
107 D40_DREG_PSEG3, 120 D40_DREG_PSEG3,
@@ -120,7 +133,32 @@ static u32 d40_backup_regs_v3[] = {
120 D40_DREG_RCEG4, 133 D40_DREG_RCEG4,
121}; 134};
122 135
123#define BACKUP_REGS_SZ_V3 ARRAY_SIZE(d40_backup_regs_v3) 136#define BACKUP_REGS_SZ_V4A ARRAY_SIZE(d40_backup_regs_v4a)
137
138static u32 d40_backup_regs_v4b[] = {
139 D40_DREG_CPSEG1,
140 D40_DREG_CPSEG2,
141 D40_DREG_CPSEG3,
142 D40_DREG_CPSEG4,
143 D40_DREG_CPSEG5,
144 D40_DREG_CPCEG1,
145 D40_DREG_CPCEG2,
146 D40_DREG_CPCEG3,
147 D40_DREG_CPCEG4,
148 D40_DREG_CPCEG5,
149 D40_DREG_CRSEG1,
150 D40_DREG_CRSEG2,
151 D40_DREG_CRSEG3,
152 D40_DREG_CRSEG4,
153 D40_DREG_CRSEG5,
154 D40_DREG_CRCEG1,
155 D40_DREG_CRCEG2,
156 D40_DREG_CRCEG3,
157 D40_DREG_CRCEG4,
158 D40_DREG_CRCEG5,
159};
160
161#define BACKUP_REGS_SZ_V4B ARRAY_SIZE(d40_backup_regs_v4b)
124 162
125static u32 d40_backup_regs_chan[] = { 163static u32 d40_backup_regs_chan[] = {
126 D40_CHAN_REG_SSCFG, 164 D40_CHAN_REG_SSCFG,
@@ -134,6 +172,102 @@ static u32 d40_backup_regs_chan[] = {
134}; 172};
135 173
136/** 174/**
175 * struct d40_interrupt_lookup - lookup table for interrupt handler
176 *
177 * @src: Interrupt mask register.
178 * @clr: Interrupt clear register.
179 * @is_error: true if this is an error interrupt.
180 * @offset: start delta in the lookup_log_chans in d40_base. If equals to
181 * D40_PHY_CHAN, the lookup_phy_chans shall be used instead.
182 */
183struct d40_interrupt_lookup {
184 u32 src;
185 u32 clr;
186 bool is_error;
187 int offset;
188};
189
190
191static struct d40_interrupt_lookup il_v4a[] = {
192 {D40_DREG_LCTIS0, D40_DREG_LCICR0, false, 0},
193 {D40_DREG_LCTIS1, D40_DREG_LCICR1, false, 32},
194 {D40_DREG_LCTIS2, D40_DREG_LCICR2, false, 64},
195 {D40_DREG_LCTIS3, D40_DREG_LCICR3, false, 96},
196 {D40_DREG_LCEIS0, D40_DREG_LCICR0, true, 0},
197 {D40_DREG_LCEIS1, D40_DREG_LCICR1, true, 32},
198 {D40_DREG_LCEIS2, D40_DREG_LCICR2, true, 64},
199 {D40_DREG_LCEIS3, D40_DREG_LCICR3, true, 96},
200 {D40_DREG_PCTIS, D40_DREG_PCICR, false, D40_PHY_CHAN},
201 {D40_DREG_PCEIS, D40_DREG_PCICR, true, D40_PHY_CHAN},
202};
203
204static struct d40_interrupt_lookup il_v4b[] = {
205 {D40_DREG_CLCTIS1, D40_DREG_CLCICR1, false, 0},
206 {D40_DREG_CLCTIS2, D40_DREG_CLCICR2, false, 32},
207 {D40_DREG_CLCTIS3, D40_DREG_CLCICR3, false, 64},
208 {D40_DREG_CLCTIS4, D40_DREG_CLCICR4, false, 96},
209 {D40_DREG_CLCTIS5, D40_DREG_CLCICR5, false, 128},
210 {D40_DREG_CLCEIS1, D40_DREG_CLCICR1, true, 0},
211 {D40_DREG_CLCEIS2, D40_DREG_CLCICR2, true, 32},
212 {D40_DREG_CLCEIS3, D40_DREG_CLCICR3, true, 64},
213 {D40_DREG_CLCEIS4, D40_DREG_CLCICR4, true, 96},
214 {D40_DREG_CLCEIS5, D40_DREG_CLCICR5, true, 128},
215 {D40_DREG_CPCTIS, D40_DREG_CPCICR, false, D40_PHY_CHAN},
216 {D40_DREG_CPCEIS, D40_DREG_CPCICR, true, D40_PHY_CHAN},
217};
218
219/**
220 * struct d40_reg_val - simple lookup struct
221 *
222 * @reg: The register.
223 * @val: The value that belongs to the register in reg.
224 */
225struct d40_reg_val {
226 unsigned int reg;
227 unsigned int val;
228};
229
230static __initdata struct d40_reg_val dma_init_reg_v4a[] = {
231 /* Clock every part of the DMA block from start */
232 { .reg = D40_DREG_GCC, .val = D40_DREG_GCC_ENABLE_ALL},
233
234 /* Interrupts on all logical channels */
235 { .reg = D40_DREG_LCMIS0, .val = 0xFFFFFFFF},
236 { .reg = D40_DREG_LCMIS1, .val = 0xFFFFFFFF},
237 { .reg = D40_DREG_LCMIS2, .val = 0xFFFFFFFF},
238 { .reg = D40_DREG_LCMIS3, .val = 0xFFFFFFFF},
239 { .reg = D40_DREG_LCICR0, .val = 0xFFFFFFFF},
240 { .reg = D40_DREG_LCICR1, .val = 0xFFFFFFFF},
241 { .reg = D40_DREG_LCICR2, .val = 0xFFFFFFFF},
242 { .reg = D40_DREG_LCICR3, .val = 0xFFFFFFFF},
243 { .reg = D40_DREG_LCTIS0, .val = 0xFFFFFFFF},
244 { .reg = D40_DREG_LCTIS1, .val = 0xFFFFFFFF},
245 { .reg = D40_DREG_LCTIS2, .val = 0xFFFFFFFF},
246 { .reg = D40_DREG_LCTIS3, .val = 0xFFFFFFFF}
247};
248static __initdata struct d40_reg_val dma_init_reg_v4b[] = {
249 /* Clock every part of the DMA block from start */
250 { .reg = D40_DREG_GCC, .val = D40_DREG_GCC_ENABLE_ALL},
251
252 /* Interrupts on all logical channels */
253 { .reg = D40_DREG_CLCMIS1, .val = 0xFFFFFFFF},
254 { .reg = D40_DREG_CLCMIS2, .val = 0xFFFFFFFF},
255 { .reg = D40_DREG_CLCMIS3, .val = 0xFFFFFFFF},
256 { .reg = D40_DREG_CLCMIS4, .val = 0xFFFFFFFF},
257 { .reg = D40_DREG_CLCMIS5, .val = 0xFFFFFFFF},
258 { .reg = D40_DREG_CLCICR1, .val = 0xFFFFFFFF},
259 { .reg = D40_DREG_CLCICR2, .val = 0xFFFFFFFF},
260 { .reg = D40_DREG_CLCICR3, .val = 0xFFFFFFFF},
261 { .reg = D40_DREG_CLCICR4, .val = 0xFFFFFFFF},
262 { .reg = D40_DREG_CLCICR5, .val = 0xFFFFFFFF},
263 { .reg = D40_DREG_CLCTIS1, .val = 0xFFFFFFFF},
264 { .reg = D40_DREG_CLCTIS2, .val = 0xFFFFFFFF},
265 { .reg = D40_DREG_CLCTIS3, .val = 0xFFFFFFFF},
266 { .reg = D40_DREG_CLCTIS4, .val = 0xFFFFFFFF},
267 { .reg = D40_DREG_CLCTIS5, .val = 0xFFFFFFFF}
268};
269
270/**
137 * struct d40_lli_pool - Structure for keeping LLIs in memory 271 * struct d40_lli_pool - Structure for keeping LLIs in memory
138 * 272 *
139 * @base: Pointer to memory area when the pre_alloc_lli's are not large 273 * @base: Pointer to memory area when the pre_alloc_lli's are not large
@@ -221,6 +355,7 @@ struct d40_lcla_pool {
221 * @allocated_dst: Same as for src but is dst. 355 * @allocated_dst: Same as for src but is dst.
222 * allocated_dst and allocated_src uses the D40_ALLOC* defines as well as 356 * allocated_dst and allocated_src uses the D40_ALLOC* defines as well as
223 * event line number. 357 * event line number.
358 * @use_soft_lli: To mark if the linked lists of channel are managed by SW.
224 */ 359 */
225struct d40_phy_res { 360struct d40_phy_res {
226 spinlock_t lock; 361 spinlock_t lock;
@@ -228,6 +363,7 @@ struct d40_phy_res {
228 int num; 363 int num;
229 u32 allocated_src; 364 u32 allocated_src;
230 u32 allocated_dst;