Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/common/pl330.c
10817 views
1
/* linux/arch/arm/common/pl330.c
2
*
3
* Copyright (C) 2010 Samsung Electronics Co Ltd.
4
* Jaswinder Singh <[email protected]>
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
*/
20
21
#include <linux/kernel.h>
22
#include <linux/init.h>
23
#include <linux/slab.h>
24
#include <linux/module.h>
25
#include <linux/string.h>
26
#include <linux/io.h>
27
#include <linux/delay.h>
28
#include <linux/interrupt.h>
29
#include <linux/dma-mapping.h>
30
31
#include <asm/hardware/pl330.h>
32
33
/* Register and Bit field Definitions */
34
#define DS 0x0
35
#define DS_ST_STOP 0x0
36
#define DS_ST_EXEC 0x1
37
#define DS_ST_CMISS 0x2
38
#define DS_ST_UPDTPC 0x3
39
#define DS_ST_WFE 0x4
40
#define DS_ST_ATBRR 0x5
41
#define DS_ST_QBUSY 0x6
42
#define DS_ST_WFP 0x7
43
#define DS_ST_KILL 0x8
44
#define DS_ST_CMPLT 0x9
45
#define DS_ST_FLTCMP 0xe
46
#define DS_ST_FAULT 0xf
47
48
#define DPC 0x4
49
#define INTEN 0x20
50
#define ES 0x24
51
#define INTSTATUS 0x28
52
#define INTCLR 0x2c
53
#define FSM 0x30
54
#define FSC 0x34
55
#define FTM 0x38
56
57
#define _FTC 0x40
58
#define FTC(n) (_FTC + (n)*0x4)
59
60
#define _CS 0x100
61
#define CS(n) (_CS + (n)*0x8)
62
#define CS_CNS (1 << 21)
63
64
#define _CPC 0x104
65
#define CPC(n) (_CPC + (n)*0x8)
66
67
#define _SA 0x400
68
#define SA(n) (_SA + (n)*0x20)
69
70
#define _DA 0x404
71
#define DA(n) (_DA + (n)*0x20)
72
73
#define _CC 0x408
74
#define CC(n) (_CC + (n)*0x20)
75
76
#define CC_SRCINC (1 << 0)
77
#define CC_DSTINC (1 << 14)
78
#define CC_SRCPRI (1 << 8)
79
#define CC_DSTPRI (1 << 22)
80
#define CC_SRCNS (1 << 9)
81
#define CC_DSTNS (1 << 23)
82
#define CC_SRCIA (1 << 10)
83
#define CC_DSTIA (1 << 24)
84
#define CC_SRCBRSTLEN_SHFT 4
85
#define CC_DSTBRSTLEN_SHFT 18
86
#define CC_SRCBRSTSIZE_SHFT 1
87
#define CC_DSTBRSTSIZE_SHFT 15
88
#define CC_SRCCCTRL_SHFT 11
89
#define CC_SRCCCTRL_MASK 0x7
90
#define CC_DSTCCTRL_SHFT 25
91
#define CC_DRCCCTRL_MASK 0x7
92
#define CC_SWAP_SHFT 28
93
94
#define _LC0 0x40c
95
#define LC0(n) (_LC0 + (n)*0x20)
96
97
#define _LC1 0x410
98
#define LC1(n) (_LC1 + (n)*0x20)
99
100
#define DBGSTATUS 0xd00
101
#define DBG_BUSY (1 << 0)
102
103
#define DBGCMD 0xd04
104
#define DBGINST0 0xd08
105
#define DBGINST1 0xd0c
106
107
#define CR0 0xe00
108
#define CR1 0xe04
109
#define CR2 0xe08
110
#define CR3 0xe0c
111
#define CR4 0xe10
112
#define CRD 0xe14
113
114
#define PERIPH_ID 0xfe0
115
#define PCELL_ID 0xff0
116
117
#define CR0_PERIPH_REQ_SET (1 << 0)
118
#define CR0_BOOT_EN_SET (1 << 1)
119
#define CR0_BOOT_MAN_NS (1 << 2)
120
#define CR0_NUM_CHANS_SHIFT 4
121
#define CR0_NUM_CHANS_MASK 0x7
122
#define CR0_NUM_PERIPH_SHIFT 12
123
#define CR0_NUM_PERIPH_MASK 0x1f
124
#define CR0_NUM_EVENTS_SHIFT 17
125
#define CR0_NUM_EVENTS_MASK 0x1f
126
127
#define CR1_ICACHE_LEN_SHIFT 0
128
#define CR1_ICACHE_LEN_MASK 0x7
129
#define CR1_NUM_ICACHELINES_SHIFT 4
130
#define CR1_NUM_ICACHELINES_MASK 0xf
131
132
#define CRD_DATA_WIDTH_SHIFT 0
133
#define CRD_DATA_WIDTH_MASK 0x7
134
#define CRD_WR_CAP_SHIFT 4
135
#define CRD_WR_CAP_MASK 0x7
136
#define CRD_WR_Q_DEP_SHIFT 8
137
#define CRD_WR_Q_DEP_MASK 0xf
138
#define CRD_RD_CAP_SHIFT 12
139
#define CRD_RD_CAP_MASK 0x7
140
#define CRD_RD_Q_DEP_SHIFT 16
141
#define CRD_RD_Q_DEP_MASK 0xf
142
#define CRD_DATA_BUFF_SHIFT 20
143
#define CRD_DATA_BUFF_MASK 0x3ff
144
145
#define PART 0x330
146
#define DESIGNER 0x41
147
#define REVISION 0x0
148
#define INTEG_CFG 0x0
149
#define PERIPH_ID_VAL ((PART << 0) | (DESIGNER << 12))
150
151
#define PCELL_ID_VAL 0xb105f00d
152
153
#define PL330_STATE_STOPPED (1 << 0)
154
#define PL330_STATE_EXECUTING (1 << 1)
155
#define PL330_STATE_WFE (1 << 2)
156
#define PL330_STATE_FAULTING (1 << 3)
157
#define PL330_STATE_COMPLETING (1 << 4)
158
#define PL330_STATE_WFP (1 << 5)
159
#define PL330_STATE_KILLING (1 << 6)
160
#define PL330_STATE_FAULT_COMPLETING (1 << 7)
161
#define PL330_STATE_CACHEMISS (1 << 8)
162
#define PL330_STATE_UPDTPC (1 << 9)
163
#define PL330_STATE_ATBARRIER (1 << 10)
164
#define PL330_STATE_QUEUEBUSY (1 << 11)
165
#define PL330_STATE_INVALID (1 << 15)
166
167
#define PL330_STABLE_STATES (PL330_STATE_STOPPED | PL330_STATE_EXECUTING \
168
| PL330_STATE_WFE | PL330_STATE_FAULTING)
169
170
#define CMD_DMAADDH 0x54
171
#define CMD_DMAEND 0x00
172
#define CMD_DMAFLUSHP 0x35
173
#define CMD_DMAGO 0xa0
174
#define CMD_DMALD 0x04
175
#define CMD_DMALDP 0x25
176
#define CMD_DMALP 0x20
177
#define CMD_DMALPEND 0x28
178
#define CMD_DMAKILL 0x01
179
#define CMD_DMAMOV 0xbc
180
#define CMD_DMANOP 0x18
181
#define CMD_DMARMB 0x12
182
#define CMD_DMASEV 0x34
183
#define CMD_DMAST 0x08
184
#define CMD_DMASTP 0x29
185
#define CMD_DMASTZ 0x0c
186
#define CMD_DMAWFE 0x36
187
#define CMD_DMAWFP 0x30
188
#define CMD_DMAWMB 0x13
189
190
#define SZ_DMAADDH 3
191
#define SZ_DMAEND 1
192
#define SZ_DMAFLUSHP 2
193
#define SZ_DMALD 1
194
#define SZ_DMALDP 2
195
#define SZ_DMALP 2
196
#define SZ_DMALPEND 2
197
#define SZ_DMAKILL 1
198
#define SZ_DMAMOV 6
199
#define SZ_DMANOP 1
200
#define SZ_DMARMB 1
201
#define SZ_DMASEV 2
202
#define SZ_DMAST 1
203
#define SZ_DMASTP 2
204
#define SZ_DMASTZ 1
205
#define SZ_DMAWFE 2
206
#define SZ_DMAWFP 2
207
#define SZ_DMAWMB 1
208
#define SZ_DMAGO 6
209
210
#define BRST_LEN(ccr) ((((ccr) >> CC_SRCBRSTLEN_SHFT) & 0xf) + 1)
211
#define BRST_SIZE(ccr) (1 << (((ccr) >> CC_SRCBRSTSIZE_SHFT) & 0x7))
212
213
#define BYTE_TO_BURST(b, ccr) ((b) / BRST_SIZE(ccr) / BRST_LEN(ccr))
214
#define BURST_TO_BYTE(c, ccr) ((c) * BRST_SIZE(ccr) * BRST_LEN(ccr))
215
216
/*
217
* With 256 bytes, we can do more than 2.5MB and 5MB xfers per req
218
* at 1byte/burst for P<->M and M<->M respectively.
219
* For typical scenario, at 1word/burst, 10MB and 20MB xfers per req
220
* should be enough for P<->M and M<->M respectively.
221
*/
222
#define MCODE_BUFF_PER_REQ 256
223
224
/*
225
* Mark a _pl330_req as free.
226
* We do it by writing DMAEND as the first instruction
227
* because no valid request is going to have DMAEND as
228
* its first instruction to execute.
229
*/
230
#define MARK_FREE(req) do { \
231
_emit_END(0, (req)->mc_cpu); \
232
(req)->mc_len = 0; \
233
} while (0)
234
235
/* If the _pl330_req is available to the client */
236
#define IS_FREE(req) (*((u8 *)((req)->mc_cpu)) == CMD_DMAEND)
237
238
/* Use this _only_ to wait on transient states */
239
#define UNTIL(t, s) while (!(_state(t) & (s))) cpu_relax();
240
241
#ifdef PL330_DEBUG_MCGEN
242
static unsigned cmd_line;
243
#define PL330_DBGCMD_DUMP(off, x...) do { \
244
printk("%x:", cmd_line); \
245
printk(x); \
246
cmd_line += off; \
247
} while (0)
248
#define PL330_DBGMC_START(addr) (cmd_line = addr)
249
#else
250
#define PL330_DBGCMD_DUMP(off, x...) do {} while (0)
251
#define PL330_DBGMC_START(addr) do {} while (0)
252
#endif
253
254
struct _xfer_spec {
255
u32 ccr;
256
struct pl330_req *r;
257
struct pl330_xfer *x;
258
};
259
260
enum dmamov_dst {
261
SAR = 0,
262
CCR,
263
DAR,
264
};
265
266
enum pl330_dst {
267
SRC = 0,
268
DST,
269
};
270
271
enum pl330_cond {
272
SINGLE,
273
BURST,
274
ALWAYS,
275
};
276
277
struct _pl330_req {
278
u32 mc_bus;
279
void *mc_cpu;
280
/* Number of bytes taken to setup MC for the req */
281
u32 mc_len;
282
struct pl330_req *r;
283
/* Hook to attach to DMAC's list of reqs with due callback */
284
struct list_head rqd;
285
};
286
287
/* ToBeDone for tasklet */
288
struct _pl330_tbd {
289
bool reset_dmac;
290
bool reset_mngr;
291
u8 reset_chan;
292
};
293
294
/* A DMAC Thread */
295
struct pl330_thread {
296
u8 id;
297
int ev;
298
/* If the channel is not yet acquired by any client */
299
bool free;
300
/* Parent DMAC */
301
struct pl330_dmac *dmac;
302
/* Only two at a time */
303
struct _pl330_req req[2];
304
/* Index of the last submitted request */
305
unsigned lstenq;
306
};
307
308
enum pl330_dmac_state {
309
UNINIT,
310
INIT,
311
DYING,
312
};
313
314
/* A DMAC */
315
struct pl330_dmac {
316
spinlock_t lock;
317
/* Holds list of reqs with due callbacks */
318
struct list_head req_done;
319
/* Pointer to platform specific stuff */
320
struct pl330_info *pinfo;
321
/* Maximum possible events/irqs */
322
int events[32];
323
/* BUS address of MicroCode buffer */
324
u32 mcode_bus;
325
/* CPU address of MicroCode buffer */
326
void *mcode_cpu;
327
/* List of all Channel threads */
328
struct pl330_thread *channels;
329
/* Pointer to the MANAGER thread */
330
struct pl330_thread *manager;
331
/* To handle bad news in interrupt */
332
struct tasklet_struct tasks;
333
struct _pl330_tbd dmac_tbd;
334
/* State of DMAC operation */
335
enum pl330_dmac_state state;
336
};
337
338
static inline void _callback(struct pl330_req *r, enum pl330_op_err err)
339
{
340
if (r && r->xfer_cb)
341
r->xfer_cb(r->token, err);
342
}
343
344
static inline bool _queue_empty(struct pl330_thread *thrd)
345
{
346
return (IS_FREE(&thrd->req[0]) && IS_FREE(&thrd->req[1]))
347
? true : false;
348
}
349
350
static inline bool _queue_full(struct pl330_thread *thrd)
351
{
352
return (IS_FREE(&thrd->req[0]) || IS_FREE(&thrd->req[1]))
353
? false : true;
354
}
355
356
static inline bool is_manager(struct pl330_thread *thrd)
357
{
358
struct pl330_dmac *pl330 = thrd->dmac;
359
360
/* MANAGER is indexed at the end */
361
if (thrd->id == pl330->pinfo->pcfg.num_chan)
362
return true;
363
else
364
return false;
365
}
366
367
/* If manager of the thread is in Non-Secure mode */
368
static inline bool _manager_ns(struct pl330_thread *thrd)
369
{
370
struct pl330_dmac *pl330 = thrd->dmac;
371
372
return (pl330->pinfo->pcfg.mode & DMAC_MODE_NS) ? true : false;
373
}
374
375
static inline u32 get_id(struct pl330_info *pi, u32 off)
376
{
377
void __iomem *regs = pi->base;
378
u32 id = 0;
379
380
id |= (readb(regs + off + 0x0) << 0);
381
id |= (readb(regs + off + 0x4) << 8);
382
id |= (readb(regs + off + 0x8) << 16);
383
id |= (readb(regs + off + 0xc) << 24);
384
385
return id;
386
}
387
388
static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[],
389
enum pl330_dst da, u16 val)
390
{
391
if (dry_run)
392
return SZ_DMAADDH;
393
394
buf[0] = CMD_DMAADDH;
395
buf[0] |= (da << 1);
396
*((u16 *)&buf[1]) = val;
397
398
PL330_DBGCMD_DUMP(SZ_DMAADDH, "\tDMAADDH %s %u\n",
399
da == 1 ? "DA" : "SA", val);
400
401
return SZ_DMAADDH;
402
}
403
404
static inline u32 _emit_END(unsigned dry_run, u8 buf[])
405
{
406
if (dry_run)
407
return SZ_DMAEND;
408
409
buf[0] = CMD_DMAEND;
410
411
PL330_DBGCMD_DUMP(SZ_DMAEND, "\tDMAEND\n");
412
413
return SZ_DMAEND;
414
}
415
416
static inline u32 _emit_FLUSHP(unsigned dry_run, u8 buf[], u8 peri)
417
{
418
if (dry_run)
419
return SZ_DMAFLUSHP;
420
421
buf[0] = CMD_DMAFLUSHP;
422
423
peri &= 0x1f;
424
peri <<= 3;
425
buf[1] = peri;
426
427
PL330_DBGCMD_DUMP(SZ_DMAFLUSHP, "\tDMAFLUSHP %u\n", peri >> 3);
428
429
return SZ_DMAFLUSHP;
430
}
431
432
static inline u32 _emit_LD(unsigned dry_run, u8 buf[], enum pl330_cond cond)
433
{
434
if (dry_run)
435
return SZ_DMALD;
436
437
buf[0] = CMD_DMALD;
438
439
if (cond == SINGLE)
440
buf[0] |= (0 << 1) | (1 << 0);
441
else if (cond == BURST)
442
buf[0] |= (1 << 1) | (1 << 0);
443
444
PL330_DBGCMD_DUMP(SZ_DMALD, "\tDMALD%c\n",
445
cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'));
446
447
return SZ_DMALD;
448
}
449
450
static inline u32 _emit_LDP(unsigned dry_run, u8 buf[],
451
enum pl330_cond cond, u8 peri)
452
{
453
if (dry_run)
454
return SZ_DMALDP;
455
456
buf[0] = CMD_DMALDP;
457
458
if (cond == BURST)
459
buf[0] |= (1 << 1);
460
461
peri &= 0x1f;
462
peri <<= 3;
463
buf[1] = peri;
464
465
PL330_DBGCMD_DUMP(SZ_DMALDP, "\tDMALDP%c %u\n",
466
cond == SINGLE ? 'S' : 'B', peri >> 3);
467
468
return SZ_DMALDP;
469
}
470
471
static inline u32 _emit_LP(unsigned dry_run, u8 buf[],
472
unsigned loop, u8 cnt)
473
{
474
if (dry_run)
475
return SZ_DMALP;
476
477
buf[0] = CMD_DMALP;
478
479
if (loop)
480
buf[0] |= (1 << 1);
481
482
cnt--; /* DMAC increments by 1 internally */
483
buf[1] = cnt;
484
485
PL330_DBGCMD_DUMP(SZ_DMALP, "\tDMALP_%c %u\n", loop ? '1' : '0', cnt);
486
487
return SZ_DMALP;
488
}
489
490
struct _arg_LPEND {
491
enum pl330_cond cond;
492
bool forever;
493
unsigned loop;
494
u8 bjump;
495
};
496
497
static inline u32 _emit_LPEND(unsigned dry_run, u8 buf[],
498
const struct _arg_LPEND *arg)
499
{
500
enum pl330_cond cond = arg->cond;
501
bool forever = arg->forever;
502
unsigned loop = arg->loop;
503
u8 bjump = arg->bjump;
504
505
if (dry_run)
506
return SZ_DMALPEND;
507
508
buf[0] = CMD_DMALPEND;
509
510
if (loop)
511
buf[0] |= (1 << 2);
512
513
if (!forever)
514
buf[0] |= (1 << 4);
515
516
if (cond == SINGLE)
517
buf[0] |= (0 << 1) | (1 << 0);
518
else if (cond == BURST)
519
buf[0] |= (1 << 1) | (1 << 0);
520
521
buf[1] = bjump;
522
523
PL330_DBGCMD_DUMP(SZ_DMALPEND, "\tDMALP%s%c_%c bjmpto_%x\n",
524
forever ? "FE" : "END",
525
cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'),
526
loop ? '1' : '0',
527
bjump);
528
529
return SZ_DMALPEND;
530
}
531
532
static inline u32 _emit_KILL(unsigned dry_run, u8 buf[])
533
{
534
if (dry_run)
535
return SZ_DMAKILL;
536
537
buf[0] = CMD_DMAKILL;
538
539
return SZ_DMAKILL;
540
}
541
542
static inline u32 _emit_MOV(unsigned dry_run, u8 buf[],
543
enum dmamov_dst dst, u32 val)
544
{
545
if (dry_run)
546
return SZ_DMAMOV;
547
548
buf[0] = CMD_DMAMOV;
549
buf[1] = dst;
550
*((u32 *)&buf[2]) = val;
551
552
PL330_DBGCMD_DUMP(SZ_DMAMOV, "\tDMAMOV %s 0x%x\n",
553
dst == SAR ? "SAR" : (dst == DAR ? "DAR" : "CCR"), val);
554
555
return SZ_DMAMOV;
556
}
557
558
static inline u32 _emit_NOP(unsigned dry_run, u8 buf[])
559
{
560
if (dry_run)
561
return SZ_DMANOP;
562
563
buf[0] = CMD_DMANOP;
564
565
PL330_DBGCMD_DUMP(SZ_DMANOP, "\tDMANOP\n");
566
567
return SZ_DMANOP;
568
}
569
570
static inline u32 _emit_RMB(unsigned dry_run, u8 buf[])
571
{
572
if (dry_run)
573
return SZ_DMARMB;
574
575
buf[0] = CMD_DMARMB;
576
577
PL330_DBGCMD_DUMP(SZ_DMARMB, "\tDMARMB\n");
578
579
return SZ_DMARMB;
580
}
581
582
static inline u32 _emit_SEV(unsigned dry_run, u8 buf[], u8 ev)
583
{
584
if (dry_run)
585
return SZ_DMASEV;
586
587
buf[0] = CMD_DMASEV;
588
589
ev &= 0x1f;
590
ev <<= 3;
591
buf[1] = ev;
592
593
PL330_DBGCMD_DUMP(SZ_DMASEV, "\tDMASEV %u\n", ev >> 3);
594
595
return SZ_DMASEV;
596
}
597
598
static inline u32 _emit_ST(unsigned dry_run, u8 buf[], enum pl330_cond cond)
599
{
600
if (dry_run)
601
return SZ_DMAST;
602
603
buf[0] = CMD_DMAST;
604
605
if (cond == SINGLE)
606
buf[0] |= (0 << 1) | (1 << 0);
607
else if (cond == BURST)
608
buf[0] |= (1 << 1) | (1 << 0);
609
610
PL330_DBGCMD_DUMP(SZ_DMAST, "\tDMAST%c\n",
611
cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'));
612
613
return SZ_DMAST;
614
}
615
616
static inline u32 _emit_STP(unsigned dry_run, u8 buf[],
617
enum pl330_cond cond, u8 peri)
618
{
619
if (dry_run)
620
return SZ_DMASTP;
621
622
buf[0] = CMD_DMASTP;
623
624
if (cond == BURST)
625
buf[0] |= (1 << 1);
626
627
peri &= 0x1f;
628
peri <<= 3;
629
buf[1] = peri;
630
631
PL330_DBGCMD_DUMP(SZ_DMASTP, "\tDMASTP%c %u\n",
632
cond == SINGLE ? 'S' : 'B', peri >> 3);
633
634
return SZ_DMASTP;
635
}
636
637
static inline u32 _emit_STZ(unsigned dry_run, u8 buf[])
638
{
639
if (dry_run)
640
return SZ_DMASTZ;
641
642
buf[0] = CMD_DMASTZ;
643
644
PL330_DBGCMD_DUMP(SZ_DMASTZ, "\tDMASTZ\n");
645
646
return SZ_DMASTZ;
647
}
648
649
static inline u32 _emit_WFE(unsigned dry_run, u8 buf[], u8 ev,
650
unsigned invalidate)
651
{
652
if (dry_run)
653
return SZ_DMAWFE;
654
655
buf[0] = CMD_DMAWFE;
656
657
ev &= 0x1f;
658
ev <<= 3;
659
buf[1] = ev;
660
661
if (invalidate)
662
buf[1] |= (1 << 1);
663
664
PL330_DBGCMD_DUMP(SZ_DMAWFE, "\tDMAWFE %u%s\n",
665
ev >> 3, invalidate ? ", I" : "");
666
667
return SZ_DMAWFE;
668
}
669
670
static inline u32 _emit_WFP(unsigned dry_run, u8 buf[],
671
enum pl330_cond cond, u8 peri)
672
{
673
if (dry_run)
674
return SZ_DMAWFP;
675
676
buf[0] = CMD_DMAWFP;
677
678
if (cond == SINGLE)
679
buf[0] |= (0 << 1) | (0 << 0);
680
else if (cond == BURST)
681
buf[0] |= (1 << 1) | (0 << 0);
682
else
683
buf[0] |= (0 << 1) | (1 << 0);
684
685
peri &= 0x1f;
686
peri <<= 3;
687
buf[1] = peri;
688
689
PL330_DBGCMD_DUMP(SZ_DMAWFP, "\tDMAWFP%c %u\n",
690
cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'P'), peri >> 3);
691
692
return SZ_DMAWFP;
693
}
694
695
static inline u32 _emit_WMB(unsigned dry_run, u8 buf[])
696
{
697
if (dry_run)
698
return SZ_DMAWMB;
699
700
buf[0] = CMD_DMAWMB;
701
702
PL330_DBGCMD_DUMP(SZ_DMAWMB, "\tDMAWMB\n");
703
704
return SZ_DMAWMB;
705
}
706
707
struct _arg_GO {
708
u8 chan;
709
u32 addr;
710
unsigned ns;
711
};
712
713
static inline u32 _emit_GO(unsigned dry_run, u8 buf[],
714
const struct _arg_GO *arg)
715
{
716
u8 chan = arg->chan;
717
u32 addr = arg->addr;
718
unsigned ns = arg->ns;
719
720
if (dry_run)
721
return SZ_DMAGO;
722
723
buf[0] = CMD_DMAGO;
724
buf[0] |= (ns << 1);
725
726
buf[1] = chan & 0x7;
727
728
*((u32 *)&buf[2]) = addr;
729
730
return SZ_DMAGO;
731
}
732
733
#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
734
735
/* Returns Time-Out */
736
static bool _until_dmac_idle(struct pl330_thread *thrd)
737
{
738
void __iomem *regs = thrd->dmac->pinfo->base;
739
unsigned long loops = msecs_to_loops(5);
740
741
do {
742
/* Until Manager is Idle */
743
if (!(readl(regs + DBGSTATUS) & DBG_BUSY))
744
break;
745
746
cpu_relax();
747
} while (--loops);
748
749
if (!loops)
750
return true;
751
752
return false;
753
}
754
755
static inline void _execute_DBGINSN(struct pl330_thread *thrd,
756
u8 insn[], bool as_manager)
757
{
758
void __iomem *regs = thrd->dmac->pinfo->base;
759
u32 val;
760
761
val = (insn[0] << 16) | (insn[1] << 24);
762
if (!as_manager) {
763
val |= (1 << 0);
764
val |= (thrd->id << 8); /* Channel Number */
765
}
766
writel(val, regs + DBGINST0);
767
768
val = *((u32 *)&insn[2]);
769
writel(val, regs + DBGINST1);
770
771
/* If timed out due to halted state-machine */
772
if (_until_dmac_idle(thrd)) {
773
dev_err(thrd->dmac->pinfo->dev, "DMAC halted!\n");
774
return;
775
}
776
777
/* Get going */
778
writel(0, regs + DBGCMD);
779
}
780
781
static inline u32 _state(struct pl330_thread *thrd)
782
{
783
void __iomem *regs = thrd->dmac->pinfo->base;
784
u32 val;
785
786
if (is_manager(thrd))
787
val = readl(regs + DS) & 0xf;
788
else
789
val = readl(regs + CS(thrd->id)) & 0xf;
790
791
switch (val) {
792
case DS_ST_STOP:
793
return PL330_STATE_STOPPED;
794
case DS_ST_EXEC:
795
return PL330_STATE_EXECUTING;
796
case DS_ST_CMISS:
797
return PL330_STATE_CACHEMISS;
798
case DS_ST_UPDTPC:
799
return PL330_STATE_UPDTPC;
800
case DS_ST_WFE:
801
return PL330_STATE_WFE;
802
case DS_ST_FAULT:
803
return PL330_STATE_FAULTING;
804
case DS_ST_ATBRR:
805
if (is_manager(thrd))
806
return PL330_STATE_INVALID;
807
else
808
return PL330_STATE_ATBARRIER;
809
case DS_ST_QBUSY:
810
if (is_manager(thrd))
811
return PL330_STATE_INVALID;
812
else
813
return PL330_STATE_QUEUEBUSY;
814
case DS_ST_WFP:
815
if (is_manager(thrd))
816
return PL330_STATE_INVALID;
817
else
818
return PL330_STATE_WFP;
819
case DS_ST_KILL:
820
if (is_manager(thrd))
821
return PL330_STATE_INVALID;
822
else
823
return PL330_STATE_KILLING;
824
case DS_ST_CMPLT:
825
if (is_manager(thrd))
826
return PL330_STATE_INVALID;
827
else
828
return PL330_STATE_COMPLETING;
829
case DS_ST_FLTCMP:
830
if (is_manager(thrd))
831
return PL330_STATE_INVALID;
832
else
833
return PL330_STATE_FAULT_COMPLETING;
834
default:
835
return PL330_STATE_INVALID;
836
}
837
}
838
839
/* If the request 'req' of thread 'thrd' is currently active */
840
static inline bool _req_active(struct pl330_thread *thrd,
841
struct _pl330_req *req)
842
{
843
void __iomem *regs = thrd->dmac->pinfo->base;
844
u32 buf = req->mc_bus, pc = readl(regs + CPC(thrd->id));
845
846
if (IS_FREE(req))
847
return false;
848
849
return (pc >= buf && pc <= buf + req->mc_len) ? true : false;
850
}
851
852
/* Returns 0 if the thread is inactive, ID of active req + 1 otherwise */
853
static inline unsigned _thrd_active(struct pl330_thread *thrd)
854
{
855
if (_req_active(thrd, &thrd->req[0]))
856
return 1; /* First req active */
857
858
if (_req_active(thrd, &thrd->req[1]))
859
return 2; /* Second req active */
860
861
return 0;
862
}
863
864
static void _stop(struct pl330_thread *thrd)
865
{
866
void __iomem *regs = thrd->dmac->pinfo->base;
867
u8 insn[6] = {0, 0, 0, 0, 0, 0};
868
869
if (_state(thrd) == PL330_STATE_FAULT_COMPLETING)
870
UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING);
871
872
/* Return if nothing needs to be done */
873
if (_state(thrd) == PL330_STATE_COMPLETING
874
|| _state(thrd) == PL330_STATE_KILLING
875
|| _state(thrd) == PL330_STATE_STOPPED)
876
return;
877
878
_emit_KILL(0, insn);
879
880
/* Stop generating interrupts for SEV */
881
writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN);
882
883
_execute_DBGINSN(thrd, insn, is_manager(thrd));
884
}
885
886
/* Start doing req 'idx' of thread 'thrd' */
887
static bool _trigger(struct pl330_thread *thrd)
888
{
889
void __iomem *regs = thrd->dmac->pinfo->base;
890
struct _pl330_req *req;
891
struct pl330_req *r;
892
struct _arg_GO go;
893
unsigned ns;
894
u8 insn[6] = {0, 0, 0, 0, 0, 0};
895
896
/* Return if already ACTIVE */
897
if (_state(thrd) != PL330_STATE_STOPPED)
898
return true;
899
900
if (!IS_FREE(&thrd->req[1 - thrd->lstenq]))
901
req = &thrd->req[1 - thrd->lstenq];
902
else if (!IS_FREE(&thrd->req[thrd->lstenq]))
903
req = &thrd->req[thrd->lstenq];
904
else
905
req = NULL;
906
907
/* Return if no request */
908
if (!req || !req->r)
909
return true;
910
911
r = req->r;
912
913
if (r->cfg)
914
ns = r->cfg->nonsecure ? 1 : 0;
915
else if (readl(regs + CS(thrd->id)) & CS_CNS)
916
ns = 1;
917
else
918
ns = 0;
919
920
/* See 'Abort Sources' point-4 at Page 2-25 */
921
if (_manager_ns(thrd) && !ns)
922
dev_info(thrd->dmac->pinfo->dev, "%s:%d Recipe for ABORT!\n",
923
__func__, __LINE__);
924
925
go.chan = thrd->id;
926
go.addr = req->mc_bus;
927
go.ns = ns;
928
_emit_GO(0, insn, &go);
929
930
/* Set to generate interrupts for SEV */
931
writel(readl(regs + INTEN) | (1 << thrd->ev), regs + INTEN);
932
933
/* Only manager can execute GO */
934
_execute_DBGINSN(thrd, insn, true);
935
936
return true;
937
}
938
939
static bool _start(struct pl330_thread *thrd)
940
{
941
switch (_state(thrd)) {
942
case PL330_STATE_FAULT_COMPLETING:
943
UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING);
944
945
if (_state(thrd) == PL330_STATE_KILLING)
946
UNTIL(thrd, PL330_STATE_STOPPED)
947
948
case PL330_STATE_FAULTING:
949
_stop(thrd);
950
951
case PL330_STATE_KILLING:
952
case PL330_STATE_COMPLETING:
953
UNTIL(thrd, PL330_STATE_STOPPED)
954
955
case PL330_STATE_STOPPED:
956
return _trigger(thrd);
957
958
case PL330_STATE_WFP:
959
case PL330_STATE_QUEUEBUSY:
960
case PL330_STATE_ATBARRIER:
961
case PL330_STATE_UPDTPC:
962
case PL330_STATE_CACHEMISS:
963
case PL330_STATE_EXECUTING:
964
return true;
965
966
case PL330_STATE_WFE: /* For RESUME, nothing yet */
967
default:
968
return false;
969
}
970
}
971
972
static inline int _ldst_memtomem(unsigned dry_run, u8 buf[],
973
const struct _xfer_spec *pxs, int cyc)
974
{
975
int off = 0;
976
977
while (cyc--) {
978
off += _emit_LD(dry_run, &buf[off], ALWAYS);
979
off += _emit_RMB(dry_run, &buf[off]);
980
off += _emit_ST(dry_run, &buf[off], ALWAYS);
981
off += _emit_WMB(dry_run, &buf[off]);
982
}
983
984
return off;
985
}
986
987
static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
988
const struct _xfer_spec *pxs, int cyc)
989
{
990
int off = 0;
991
992
while (cyc--) {
993
off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri);
994
off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->r->peri);
995
off += _emit_ST(dry_run, &buf[off], ALWAYS);
996
off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri);
997
}
998
999
return off;
1000
}
1001
1002
static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
1003
const struct _xfer_spec *pxs, int cyc)
1004
{
1005
int off = 0;
1006
1007
while (cyc--) {
1008
off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri);
1009
off += _emit_LD(dry_run, &buf[off], ALWAYS);
1010
off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->r->peri);
1011
off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri);
1012
}
1013
1014
return off;
1015
}
1016
1017
static int _bursts(unsigned dry_run, u8 buf[],
1018
const struct _xfer_spec *pxs, int cyc)
1019
{
1020
int off = 0;
1021
1022
switch (pxs->r->rqtype) {
1023
case MEMTODEV:
1024
off += _ldst_memtodev(dry_run, &buf[off], pxs, cyc);
1025
break;
1026
case DEVTOMEM:
1027
off += _ldst_devtomem(dry_run, &buf[off], pxs, cyc);
1028
break;
1029
case MEMTOMEM:
1030
off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc);
1031
break;
1032
default:
1033
off += 0x40000000; /* Scare off the Client */
1034
break;
1035
}
1036
1037
return off;
1038
}
1039
1040
/* Returns bytes consumed and updates bursts */
1041
static inline int _loop(unsigned dry_run, u8 buf[],
1042
unsigned long *bursts, const struct _xfer_spec *pxs)
1043
{
1044
int cyc, cycmax, szlp, szlpend, szbrst, off;
1045
unsigned lcnt0, lcnt1, ljmp0, ljmp1;
1046
struct _arg_LPEND lpend;
1047
1048
/* Max iterations possible in DMALP is 256 */
1049
if (*bursts >= 256*256) {
1050
lcnt1 = 256;
1051
lcnt0 = 256;
1052
cyc = *bursts / lcnt1 / lcnt0;
1053
} else if (*bursts > 256) {
1054
lcnt1 = 256;
1055
lcnt0 = *bursts / lcnt1;
1056
cyc = 1;
1057
} else {
1058
lcnt1 = *bursts;
1059
lcnt0 = 0;
1060
cyc = 1;
1061
}
1062
1063
szlp = _emit_LP(1, buf, 0, 0);
1064
szbrst = _bursts(1, buf, pxs, 1);
1065
1066
lpend.cond = ALWAYS;
1067
lpend.forever = false;
1068
lpend.loop = 0;
1069
lpend.bjump = 0;
1070
szlpend = _emit_LPEND(1, buf, &lpend);
1071
1072
if (lcnt0) {
1073
szlp *= 2;
1074
szlpend *= 2;
1075
}
1076
1077
/*
1078
* Max bursts that we can unroll due to limit on the
1079
* size of backward jump that can be encoded in DMALPEND
1080
* which is 8-bits and hence 255
1081
*/
1082
cycmax = (255 - (szlp + szlpend)) / szbrst;
1083
1084
cyc = (cycmax < cyc) ? cycmax : cyc;
1085
1086
off = 0;
1087
1088
if (lcnt0) {
1089
off += _emit_LP(dry_run, &buf[off], 0, lcnt0);
1090
ljmp0 = off;
1091
}
1092
1093
off += _emit_LP(dry_run, &buf[off], 1, lcnt1);
1094
ljmp1 = off;
1095
1096
off += _bursts(dry_run, &buf[off], pxs, cyc);
1097
1098
lpend.cond = ALWAYS;
1099
lpend.forever = false;
1100
lpend.loop = 1;
1101
lpend.bjump = off - ljmp1;
1102
off += _emit_LPEND(dry_run, &buf[off], &lpend);
1103
1104
if (lcnt0) {
1105
lpend.cond = ALWAYS;
1106
lpend.forever = false;
1107
lpend.loop = 0;
1108
lpend.bjump = off - ljmp0;
1109
off += _emit_LPEND(dry_run, &buf[off], &lpend);
1110
}
1111
1112
*bursts = lcnt1 * cyc;
1113
if (lcnt0)
1114
*bursts *= lcnt0;
1115
1116
return off;
1117
}
1118
1119
static inline int _setup_loops(unsigned dry_run, u8 buf[],
1120
const struct _xfer_spec *pxs)
1121
{
1122
struct pl330_xfer *x = pxs->x;
1123
u32 ccr = pxs->ccr;
1124
unsigned long c, bursts = BYTE_TO_BURST(x->bytes, ccr);
1125
int off = 0;
1126
1127
while (bursts) {
1128
c = bursts;
1129
off += _loop(dry_run, &buf[off], &c, pxs);
1130
bursts -= c;
1131
}
1132
1133
return off;
1134
}
1135
1136
static inline int _setup_xfer(unsigned dry_run, u8 buf[],
1137
const struct _xfer_spec *pxs)
1138
{
1139
struct pl330_xfer *x = pxs->x;
1140
int off = 0;
1141
1142
/* DMAMOV SAR, x->src_addr */
1143
off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr);
1144
/* DMAMOV DAR, x->dst_addr */
1145
off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr);
1146
1147
/* Setup Loop(s) */
1148
off += _setup_loops(dry_run, &buf[off], pxs);
1149
1150
return off;
1151
}
1152
1153
/*
1154
* A req is a sequence of one or more xfer units.
1155
* Returns the number of bytes taken to setup the MC for the req.
1156
*/
1157
static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
1158
unsigned index, struct _xfer_spec *pxs)
1159
{
1160
struct _pl330_req *req = &thrd->req[index];
1161
struct pl330_xfer *x;
1162
u8 *buf = req->mc_cpu;
1163
int off = 0;
1164
1165
PL330_DBGMC_START(req->mc_bus);
1166
1167
/* DMAMOV CCR, ccr */
1168
off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr);
1169
1170
x = pxs->r->x;
1171
do {
1172
/* Error if xfer length is not aligned at burst size */
1173
if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr)))
1174
return -EINVAL;
1175
1176
pxs->x = x;
1177
off += _setup_xfer(dry_run, &buf[off], pxs);
1178
1179
x = x->next;
1180
} while (x);
1181
1182
/* DMASEV peripheral/event */
1183
off += _emit_SEV(dry_run, &buf[off], thrd->ev);
1184
/* DMAEND */
1185
off += _emit_END(dry_run, &buf[off]);
1186
1187
return off;
1188
}
1189
1190
static inline u32 _prepare_ccr(const struct pl330_reqcfg *rqc)
1191
{
1192
u32 ccr = 0;
1193
1194
if (rqc->src_inc)
1195
ccr |= CC_SRCINC;
1196
1197
if (rqc->dst_inc)
1198
ccr |= CC_DSTINC;
1199
1200
/* We set same protection levels for Src and DST for now */
1201
if (rqc->privileged)
1202
ccr |= CC_SRCPRI | CC_DSTPRI;
1203
if (rqc->nonsecure)
1204
ccr |= CC_SRCNS | CC_DSTNS;
1205
if (rqc->insnaccess)
1206
ccr |= CC_SRCIA | CC_DSTIA;
1207
1208
ccr |= (((rqc->brst_len - 1) & 0xf) << CC_SRCBRSTLEN_SHFT);
1209
ccr |= (((rqc->brst_len - 1) & 0xf) << CC_DSTBRSTLEN_SHFT);
1210
1211
ccr |= (rqc->brst_size << CC_SRCBRSTSIZE_SHFT);
1212
ccr |= (rqc->brst_size << CC_DSTBRSTSIZE_SHFT);
1213
1214
ccr |= (rqc->dcctl << CC_SRCCCTRL_SHFT);
1215
ccr |= (rqc->scctl << CC_DSTCCTRL_SHFT);
1216
1217
ccr |= (rqc->swap << CC_SWAP_SHFT);
1218
1219
return ccr;
1220
}
1221
1222
static inline bool _is_valid(u32 ccr)
1223
{
1224
enum pl330_dstcachectrl dcctl;
1225
enum pl330_srccachectrl scctl;
1226
1227
dcctl = (ccr >> CC_DSTCCTRL_SHFT) & CC_DRCCCTRL_MASK;
1228
scctl = (ccr >> CC_SRCCCTRL_SHFT) & CC_SRCCCTRL_MASK;
1229
1230
if (dcctl == DINVALID1 || dcctl == DINVALID2
1231
|| scctl == SINVALID1 || scctl == SINVALID2)
1232
return false;
1233
else
1234
return true;
1235
}
1236
1237
/*
1238
* Submit a list of xfers after which the client wants notification.
1239
* Client is not notified after each xfer unit, just once after all
1240
* xfer units are done or some error occurs.
1241
*/
1242
int pl330_submit_req(void *ch_id, struct pl330_req *r)
1243
{
1244
struct pl330_thread *thrd = ch_id;
1245
struct pl330_dmac *pl330;
1246
struct pl330_info *pi;
1247
struct _xfer_spec xs;
1248
unsigned long flags;
1249
void __iomem *regs;
1250
unsigned idx;
1251
u32 ccr;
1252
int ret = 0;
1253
1254
/* No Req or Unacquired Channel or DMAC */
1255
if (!r || !thrd || thrd->free)
1256
return -EINVAL;
1257
1258
pl330 = thrd->dmac;
1259
pi = pl330->pinfo;
1260
regs = pi->base;
1261
1262
if (pl330->state == DYING
1263
|| pl330->dmac_tbd.reset_chan & (1 << thrd->id)) {
1264
dev_info(thrd->dmac->pinfo->dev, "%s:%d\n",
1265
__func__, __LINE__);
1266
return -EAGAIN;
1267
}
1268
1269
/* If request for non-existing peripheral */
1270
if (r->rqtype != MEMTOMEM && r->peri >= pi->pcfg.num_peri) {
1271
dev_info(thrd->dmac->pinfo->dev,
1272
"%s:%d Invalid peripheral(%u)!\n",
1273
__func__, __LINE__, r->peri);
1274
return -EINVAL;
1275
}
1276
1277
spin_lock_irqsave(&pl330->lock, flags);
1278
1279
if (_queue_full(thrd)) {
1280
ret = -EAGAIN;
1281
goto xfer_exit;
1282
}
1283
1284
/* Prefer Secure Channel */
1285
if (!_manager_ns(thrd))
1286
r->cfg->nonsecure = 0;
1287
else
1288
r->cfg->nonsecure = 1;
1289
1290
/* Use last settings, if not provided */
1291
if (r->cfg)
1292
ccr = _prepare_ccr(r->cfg);
1293
else
1294
ccr = readl(regs + CC(thrd->id));
1295
1296
/* If this req doesn't have valid xfer settings */
1297
if (!_is_valid(ccr)) {
1298
ret = -EINVAL;
1299
dev_info(thrd->dmac->pinfo->dev, "%s:%d Invalid CCR(%x)!\n",
1300
__func__, __LINE__, ccr);
1301
goto xfer_exit;
1302
}
1303
1304
idx = IS_FREE(&thrd->req[0]) ? 0 : 1;
1305
1306
xs.ccr = ccr;
1307
xs.r = r;
1308
1309
/* First dry run to check if req is acceptable */
1310
ret = _setup_req(1, thrd, idx, &xs);
1311
if (ret < 0)
1312
goto xfer_exit;
1313
1314
if (ret > pi->mcbufsz / 2) {
1315
dev_info(thrd->dmac->pinfo->dev,
1316
"%s:%d Trying increasing mcbufsz\n",
1317
__func__, __LINE__);
1318
ret = -ENOMEM;
1319
goto xfer_exit;
1320
}
1321
1322
/* Hook the request */
1323
thrd->lstenq = idx;
1324
thrd->req[idx].mc_len = _setup_req(0, thrd, idx, &xs);
1325
thrd->req[idx].r = r;
1326
1327
ret = 0;
1328
1329
xfer_exit:
1330
spin_unlock_irqrestore(&pl330->lock, flags);
1331
1332
return ret;
1333
}
1334
EXPORT_SYMBOL(pl330_submit_req);
1335
1336
static void pl330_dotask(unsigned long data)
1337
{
1338
struct pl330_dmac *pl330 = (struct pl330_dmac *) data;
1339
struct pl330_info *pi = pl330->pinfo;
1340
unsigned long flags;
1341
int i;
1342
1343
spin_lock_irqsave(&pl330->lock, flags);
1344
1345
/* The DMAC itself gone nuts */
1346
if (pl330->dmac_tbd.reset_dmac) {
1347
pl330->state = DYING;
1348
/* Reset the manager too */
1349
pl330->dmac_tbd.reset_mngr = true;
1350
/* Clear the reset flag */
1351
pl330->dmac_tbd.reset_dmac = false;
1352
}
1353
1354
if (pl330->dmac_tbd.reset_mngr) {
1355
_stop(pl330->manager);
1356
/* Reset all channels */
1357
pl330->dmac_tbd.reset_chan = (1 << pi->pcfg.num_chan) - 1;
1358
/* Clear the reset flag */
1359
pl330->dmac_tbd.reset_mngr = false;
1360
}
1361
1362
for (i = 0; i < pi->pcfg.num_chan; i++) {
1363
1364
if (pl330->dmac_tbd.reset_chan & (1 << i)) {
1365
struct pl330_thread *thrd = &pl330->channels[i];
1366
void __iomem *regs = pi->base;
1367
enum pl330_op_err err;
1368
1369
_stop(thrd);
1370
1371
if (readl(regs + FSC) & (1 << thrd->id))
1372
err = PL330_ERR_FAIL;
1373
else
1374
err = PL330_ERR_ABORT;
1375
1376
spin_unlock_irqrestore(&pl330->lock, flags);
1377
1378
_callback(thrd->req[1 - thrd->lstenq].r, err);
1379
_callback(thrd->req[thrd->lstenq].r, err);
1380
1381
spin_lock_irqsave(&pl330->lock, flags);
1382
1383
thrd->req[0].r = NULL;
1384
thrd->req[1].r = NULL;
1385
MARK_FREE(&thrd->req[0]);
1386
MARK_FREE(&thrd->req[1]);
1387
1388
/* Clear the reset flag */
1389
pl330->dmac_tbd.reset_chan &= ~(1 << i);
1390
}
1391
}
1392
1393
spin_unlock_irqrestore(&pl330->lock, flags);
1394
1395
return;
1396
}
1397
1398
/* Returns 1 if state was updated, 0 otherwise */
1399
int pl330_update(const struct pl330_info *pi)
1400
{
1401
struct _pl330_req *rqdone;
1402
struct pl330_dmac *pl330;
1403
unsigned long flags;
1404
void __iomem *regs;
1405
u32 val;
1406
int id, ev, ret = 0;
1407
1408
if (!pi || !pi->pl330_data)
1409
return 0;
1410
1411
regs = pi->base;
1412
pl330 = pi->pl330_data;
1413
1414
spin_lock_irqsave(&pl330->lock, flags);
1415
1416
val = readl(regs + FSM) & 0x1;
1417
if (val)
1418
pl330->dmac_tbd.reset_mngr = true;
1419
else
1420
pl330->dmac_tbd.reset_mngr = false;
1421
1422
val = readl(regs + FSC) & ((1 << pi->pcfg.num_chan) - 1);
1423
pl330->dmac_tbd.reset_chan |= val;
1424
if (val) {
1425
int i = 0;
1426
while (i < pi->pcfg.num_chan) {
1427
if (val & (1 << i)) {
1428
dev_info(pi->dev,
1429
"Reset Channel-%d\t CS-%x FTC-%x\n",
1430
i, readl(regs + CS(i)),
1431
readl(regs + FTC(i)));
1432
_stop(&pl330->channels[i]);
1433
}
1434
i++;
1435
}
1436
}
1437
1438
/* Check which event happened i.e, thread notified */
1439
val = readl(regs + ES);
1440
if (pi->pcfg.num_events < 32
1441
&& val & ~((1 << pi->pcfg.num_events) - 1)) {
1442
pl330->dmac_tbd.reset_dmac = true;
1443
dev_err(pi->dev, "%s:%d Unexpected!\n", __func__, __LINE__);
1444
ret = 1;
1445
goto updt_exit;
1446
}
1447
1448
for (ev = 0; ev < pi->pcfg.num_events; ev++) {
1449
if (val & (1 << ev)) { /* Event occurred */
1450
struct pl330_thread *thrd;
1451
u32 inten = readl(regs + INTEN);
1452
int active;
1453
1454
/* Clear the event */
1455
if (inten & (1 << ev))
1456
writel(1 << ev, regs + INTCLR);
1457
1458
ret = 1;
1459
1460
id = pl330->events[ev];
1461
1462
thrd = &pl330->channels[id];
1463
1464
active = _thrd_active(thrd);
1465
if (!active) /* Aborted */
1466
continue;
1467
1468
active -= 1;
1469
1470
rqdone = &thrd->req[active];
1471
MARK_FREE(rqdone);
1472
1473
/* Get going again ASAP */
1474
_start(thrd);
1475
1476
/* For now, just make a list of callbacks to be done */
1477
list_add_tail(&rqdone->rqd, &pl330->req_done);
1478
}
1479
}
1480
1481
/* Now that we are in no hurry, do the callbacks */
1482
while (!list_empty(&pl330->req_done)) {
1483
rqdone = container_of(pl330->req_done.next,
1484
struct _pl330_req, rqd);
1485
1486
list_del_init(&rqdone->rqd);
1487
1488
spin_unlock_irqrestore(&pl330->lock, flags);
1489
_callback(rqdone->r, PL330_ERR_NONE);
1490
spin_lock_irqsave(&pl330->lock, flags);
1491
}
1492
1493
updt_exit:
1494
spin_unlock_irqrestore(&pl330->lock, flags);
1495
1496
if (pl330->dmac_tbd.reset_dmac
1497
|| pl330->dmac_tbd.reset_mngr
1498
|| pl330->dmac_tbd.reset_chan) {
1499
ret = 1;
1500
tasklet_schedule(&pl330->tasks);
1501
}
1502
1503
return ret;
1504
}
1505
EXPORT_SYMBOL(pl330_update);
1506
1507
int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op)
1508
{
1509
struct pl330_thread *thrd = ch_id;
1510
struct pl330_dmac *pl330;
1511
unsigned long flags;
1512
int ret = 0, active;
1513
1514
if (!thrd || thrd->free || thrd->dmac->state == DYING)
1515
return -EINVAL;
1516
1517
pl330 = thrd->dmac;
1518
1519
spin_lock_irqsave(&pl330->lock, flags);
1520
1521
switch (op) {
1522
case PL330_OP_FLUSH:
1523
/* Make sure the channel is stopped */
1524
_stop(thrd);
1525
1526
thrd->req[0].r = NULL;
1527
thrd->req[1].r = NULL;
1528
MARK_FREE(&thrd->req[0]);
1529
MARK_FREE(&thrd->req[1]);
1530
break;
1531
1532
case PL330_OP_ABORT:
1533
active = _thrd_active(thrd);
1534
1535
/* Make sure the channel is stopped */
1536
_stop(thrd);
1537
1538
/* ABORT is only for the active req */
1539
if (!active)
1540
break;
1541
1542
active--;
1543
1544
thrd->req[active].r = NULL;
1545
MARK_FREE(&thrd->req[active]);
1546
1547
/* Start the next */
1548
case PL330_OP_START:
1549
if (!_start(thrd))
1550
ret = -EIO;
1551
break;
1552
1553
default:
1554
ret = -EINVAL;
1555
}
1556
1557
spin_unlock_irqrestore(&pl330->lock, flags);
1558
return ret;
1559
}
1560
EXPORT_SYMBOL(pl330_chan_ctrl);
1561
1562
int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus)
1563
{
1564
struct pl330_thread *thrd = ch_id;
1565
struct pl330_dmac *pl330;
1566
struct pl330_info *pi;
1567
void __iomem *regs;
1568
int active;
1569
u32 val;
1570
1571
if (!pstatus || !thrd || thrd->free)
1572
return -EINVAL;
1573
1574
pl330 = thrd->dmac;
1575
pi = pl330->pinfo;
1576
regs = pi->base;
1577
1578
/* The client should remove the DMAC and add again */
1579
if (pl330->state == DYING)
1580
pstatus->dmac_halted = true;
1581
else
1582
pstatus->dmac_halted = false;
1583
1584
val = readl(regs + FSC);
1585
if (val & (1 << thrd->id))
1586
pstatus->faulting = true;
1587
else
1588
pstatus->faulting = false;
1589
1590
active = _thrd_active(thrd);
1591
1592
if (!active) {
1593
/* Indicate that the thread is not running */
1594
pstatus->top_req = NULL;
1595
pstatus->wait_req = NULL;
1596
} else {
1597
active--;
1598
pstatus->top_req = thrd->req[active].r;
1599
pstatus->wait_req = !IS_FREE(&thrd->req[1 - active])
1600
? thrd->req[1 - active].r : NULL;
1601
}
1602
1603
pstatus->src_addr = readl(regs + SA(thrd->id));
1604
pstatus->dst_addr = readl(regs + DA(thrd->id));
1605
1606
return 0;
1607
}
1608
EXPORT_SYMBOL(pl330_chan_status);
1609
1610
/* Reserve an event */
1611
static inline int _alloc_event(struct pl330_thread *thrd)
1612
{
1613
struct pl330_dmac *pl330 = thrd->dmac;
1614
struct pl330_info *pi = pl330->pinfo;
1615
int ev;
1616
1617
for (ev = 0; ev < pi->pcfg.num_events; ev++)
1618
if (pl330->events[ev] == -1) {
1619
pl330->events[ev] = thrd->id;
1620
return ev;
1621
}
1622
1623
return -1;
1624
}
1625
1626
/* Upon success, returns IdentityToken for the
1627
* allocated channel, NULL otherwise.
1628
*/
1629
void *pl330_request_channel(const struct pl330_info *pi)
1630
{
1631
struct pl330_thread *thrd = NULL;
1632
struct pl330_dmac *pl330;
1633
unsigned long flags;
1634
int chans, i;
1635
1636
if (!pi || !pi->pl330_data)
1637
return NULL;
1638
1639
pl330 = pi->pl330_data;
1640
1641
if (pl330->state == DYING)
1642
return NULL;
1643
1644
chans = pi->pcfg.num_chan;
1645
1646
spin_lock_irqsave(&pl330->lock, flags);
1647
1648
for (i = 0; i < chans; i++) {
1649
thrd = &pl330->channels[i];
1650
if (thrd->free) {
1651
thrd->ev = _alloc_event(thrd);
1652
if (thrd->ev >= 0) {
1653
thrd->free = false;
1654
thrd->lstenq = 1;
1655
thrd->req[0].r = NULL;
1656
MARK_FREE(&thrd->req[0]);
1657
thrd->req[1].r = NULL;
1658
MARK_FREE(&thrd->req[1]);
1659
break;
1660
}
1661
}
1662
thrd = NULL;
1663
}
1664
1665
spin_unlock_irqrestore(&pl330->lock, flags);
1666
1667
return thrd;
1668
}
1669
EXPORT_SYMBOL(pl330_request_channel);
1670
1671
/* Release an event */
1672
static inline void _free_event(struct pl330_thread *thrd, int ev)
1673
{
1674
struct pl330_dmac *pl330 = thrd->dmac;
1675
struct pl330_info *pi = pl330->pinfo;
1676
1677
/* If the event is valid and was held by the thread */
1678
if (ev >= 0 && ev < pi->pcfg.num_events
1679
&& pl330->events[ev] == thrd->id)
1680
pl330->events[ev] = -1;
1681
}
1682
1683
void pl330_release_channel(void *ch_id)
1684
{
1685
struct pl330_thread *thrd = ch_id;
1686
struct pl330_dmac *pl330;
1687
unsigned long flags;
1688
1689
if (!thrd || thrd->free)
1690
return;
1691
1692
_stop(thrd);
1693
1694
_callback(thrd->req[1 - thrd->lstenq].r, PL330_ERR_ABORT);
1695
_callback(thrd->req[thrd->lstenq].r, PL330_ERR_ABORT);
1696
1697
pl330 = thrd->dmac;
1698
1699
spin_lock_irqsave(&pl330->lock, flags);
1700
_free_event(thrd, thrd->ev);
1701
thrd->free = true;
1702
spin_unlock_irqrestore(&pl330->lock, flags);
1703
}
1704
EXPORT_SYMBOL(pl330_release_channel);
1705
1706
/* Initialize the structure for PL330 configuration, that can be used
1707
* by the client driver the make best use of the DMAC
1708
*/
1709
static void read_dmac_config(struct pl330_info *pi)
1710
{
1711
void __iomem *regs = pi->base;
1712
u32 val;
1713
1714
val = readl(regs + CRD) >> CRD_DATA_WIDTH_SHIFT;
1715
val &= CRD_DATA_WIDTH_MASK;
1716
pi->pcfg.data_bus_width = 8 * (1 << val);
1717
1718
val = readl(regs + CRD) >> CRD_DATA_BUFF_SHIFT;
1719
val &= CRD_DATA_BUFF_MASK;
1720
pi->pcfg.data_buf_dep = val + 1;
1721
1722
val = readl(regs + CR0) >> CR0_NUM_CHANS_SHIFT;
1723
val &= CR0_NUM_CHANS_MASK;
1724
val += 1;
1725
pi->pcfg.num_chan = val;
1726
1727
val = readl(regs + CR0);
1728
if (val & CR0_PERIPH_REQ_SET) {
1729
val = (val >> CR0_NUM_PERIPH_SHIFT) & CR0_NUM_PERIPH_MASK;
1730
val += 1;
1731
pi->pcfg.num_peri = val;
1732
pi->pcfg.peri_ns = readl(regs + CR4);
1733
} else {
1734
pi->pcfg.num_peri = 0;
1735
}
1736
1737
val = readl(regs + CR0);
1738
if (val & CR0_BOOT_MAN_NS)
1739
pi->pcfg.mode |= DMAC_MODE_NS;
1740
else
1741
pi->pcfg.mode &= ~DMAC_MODE_NS;
1742
1743
val = readl(regs + CR0) >> CR0_NUM_EVENTS_SHIFT;
1744
val &= CR0_NUM_EVENTS_MASK;
1745
val += 1;
1746
pi->pcfg.num_events = val;
1747
1748
pi->pcfg.irq_ns = readl(regs + CR3);
1749
1750
pi->pcfg.periph_id = get_id(pi, PERIPH_ID);
1751
pi->pcfg.pcell_id = get_id(pi, PCELL_ID);
1752
}
1753
1754
static inline void _reset_thread(struct pl330_thread *thrd)
1755
{
1756
struct pl330_dmac *pl330 = thrd->dmac;
1757
struct pl330_info *pi = pl330->pinfo;
1758
1759
thrd->req[0].mc_cpu = pl330->mcode_cpu
1760
+ (thrd->id * pi->mcbufsz);
1761
thrd->req[0].mc_bus = pl330->mcode_bus
1762
+ (thrd->id * pi->mcbufsz);
1763
thrd->req[0].r = NULL;
1764
MARK_FREE(&thrd->req[0]);
1765
1766
thrd->req[1].mc_cpu = thrd->req[0].mc_cpu
1767
+ pi->mcbufsz / 2;
1768
thrd->req[1].mc_bus = thrd->req[0].mc_bus
1769
+ pi->mcbufsz / 2;
1770
thrd->req[1].r = NULL;
1771
MARK_FREE(&thrd->req[1]);
1772
}
1773
1774
static int dmac_alloc_threads(struct pl330_dmac *pl330)
1775
{
1776
struct pl330_info *pi = pl330->pinfo;
1777
int chans = pi->pcfg.num_chan;
1778
struct pl330_thread *thrd;
1779
int i;
1780
1781
/* Allocate 1 Manager and 'chans' Channel threads */
1782
pl330->channels = kzalloc((1 + chans) * sizeof(*thrd),
1783
GFP_KERNEL);
1784
if (!pl330->channels)
1785
return -ENOMEM;
1786
1787
/* Init Channel threads */
1788
for (i = 0; i < chans; i++) {
1789
thrd = &pl330->channels[i];
1790
thrd->id = i;
1791
thrd->dmac = pl330;
1792
_reset_thread(thrd);
1793
thrd->free = true;
1794
}
1795
1796
/* MANAGER is indexed at the end */
1797
thrd = &pl330->channels[chans];
1798
thrd->id = chans;
1799
thrd->dmac = pl330;
1800
thrd->free = false;
1801
pl330->manager = thrd;
1802
1803
return 0;
1804
}
1805
1806
static int dmac_alloc_resources(struct pl330_dmac *pl330)
1807
{
1808
struct pl330_info *pi = pl330->pinfo;
1809
int chans = pi->pcfg.num_chan;
1810
int ret;
1811
1812
/*
1813
* Alloc MicroCode buffer for 'chans' Channel threads.
1814
* A channel's buffer offset is (Channel_Id * MCODE_BUFF_PERCHAN)
1815
*/
1816
pl330->mcode_cpu = dma_alloc_coherent(pi->dev,
1817
chans * pi->mcbufsz,
1818
&pl330->mcode_bus, GFP_KERNEL);
1819
if (!pl330->mcode_cpu) {
1820
dev_err(pi->dev, "%s:%d Can't allocate memory!\n",
1821
__func__, __LINE__);
1822
return -ENOMEM;
1823
}
1824
1825
ret = dmac_alloc_threads(pl330);
1826
if (ret) {
1827
dev_err(pi->dev, "%s:%d Can't to create channels for DMAC!\n",
1828
__func__, __LINE__);
1829
dma_free_coherent(pi->dev,
1830
chans * pi->mcbufsz,
1831
pl330->mcode_cpu, pl330->mcode_bus);
1832
return ret;
1833
}
1834
1835
return 0;
1836
}
1837
1838
int pl330_add(struct pl330_info *pi)
1839
{
1840
struct pl330_dmac *pl330;
1841
void __iomem *regs;
1842
int i, ret;
1843
1844
if (!pi || !pi->dev)
1845
return -EINVAL;
1846
1847
/* If already added */
1848
if (pi->pl330_data)
1849
return -EINVAL;
1850
1851
/*
1852
* If the SoC can perform reset on the DMAC, then do it
1853
* before reading its configuration.
1854
*/
1855
if (pi->dmac_reset)
1856
pi->dmac_reset(pi);
1857
1858
regs = pi->base;
1859
1860
/* Check if we can handle this DMAC */
1861
if ((get_id(pi, PERIPH_ID) & 0xfffff) != PERIPH_ID_VAL
1862
|| get_id(pi, PCELL_ID) != PCELL_ID_VAL) {
1863
dev_err(pi->dev, "PERIPH_ID 0x%x, PCELL_ID 0x%x !\n",
1864
get_id(pi, PERIPH_ID), get_id(pi, PCELL_ID));
1865
return -EINVAL;
1866
}
1867
1868
/* Read the configuration of the DMAC */
1869
read_dmac_config(pi);
1870
1871
if (pi->pcfg.num_events == 0) {
1872
dev_err(pi->dev, "%s:%d Can't work without events!\n",
1873
__func__, __LINE__);
1874
return -EINVAL;
1875
}
1876
1877
pl330 = kzalloc(sizeof(*pl330), GFP_KERNEL);
1878
if (!pl330) {
1879
dev_err(pi->dev, "%s:%d Can't allocate memory!\n",
1880
__func__, __LINE__);
1881
return -ENOMEM;
1882
}
1883
1884
/* Assign the info structure and private data */
1885
pl330->pinfo = pi;
1886
pi->pl330_data = pl330;
1887
1888
spin_lock_init(&pl330->lock);
1889
1890
INIT_LIST_HEAD(&pl330->req_done);
1891
1892
/* Use default MC buffer size if not provided */
1893
if (!pi->mcbufsz)
1894
pi->mcbufsz = MCODE_BUFF_PER_REQ * 2;
1895
1896
/* Mark all events as free */
1897
for (i = 0; i < pi->pcfg.num_events; i++)
1898
pl330->events[i] = -1;
1899
1900
/* Allocate resources needed by the DMAC */
1901
ret = dmac_alloc_resources(pl330);
1902
if (ret) {
1903
dev_err(pi->dev, "Unable to create channels for DMAC\n");
1904
kfree(pl330);
1905
return ret;
1906
}
1907
1908
tasklet_init(&pl330->tasks, pl330_dotask, (unsigned long) pl330);
1909
1910
pl330->state = INIT;
1911
1912
return 0;
1913
}
1914
EXPORT_SYMBOL(pl330_add);
1915
1916
static int dmac_free_threads(struct pl330_dmac *pl330)
1917
{
1918
struct pl330_info *pi = pl330->pinfo;
1919
int chans = pi->pcfg.num_chan;
1920
struct pl330_thread *thrd;
1921
int i;
1922
1923
/* Release Channel threads */
1924
for (i = 0; i < chans; i++) {
1925
thrd = &pl330->channels[i];
1926
pl330_release_channel((void *)thrd);
1927
}
1928
1929
/* Free memory */
1930
kfree(pl330->channels);
1931
1932
return 0;
1933
}
1934
1935
static void dmac_free_resources(struct pl330_dmac *pl330)
1936
{
1937
struct pl330_info *pi = pl330->pinfo;
1938
int chans = pi->pcfg.num_chan;
1939
1940
dmac_free_threads(pl330);
1941
1942
dma_free_coherent(pi->dev, chans * pi->mcbufsz,
1943
pl330->mcode_cpu, pl330->mcode_bus);
1944
}
1945
1946
void pl330_del(struct pl330_info *pi)
1947
{
1948
struct pl330_dmac *pl330;
1949
1950
if (!pi || !pi->pl330_data)
1951
return;
1952
1953
pl330 = pi->pl330_data;
1954
1955
pl330->state = UNINIT;
1956
1957
tasklet_kill(&pl330->tasks);
1958
1959
/* Free DMAC resources */
1960
dmac_free_resources(pl330);
1961
1962
kfree(pl330);
1963
pi->pl330_data = NULL;
1964
}
1965
EXPORT_SYMBOL(pl330_del);
1966
1967