File indexing completed on 2025-05-11 08:24:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include <stdlib.h>
0032 #include <string.h>
0033 #include <stddef.h>
0034 #include <drvmgr/drvmgr.h>
0035 #include <rtems.h>
0036 #include <rtems/bspIo.h> /* for printk */
0037 #include <bsp.h>
0038 #include <grlib/grpci2dma.h>
0039
0040 #include <grlib/grlib_impl.h>
0041
0042
0043
0044
0045
0046 #define STATIC static
0047
0048
0049 #define INLINE inline
0050
0051
0052 #define UNUSED __attribute__((unused))
0053
0054
0055
0056 #ifdef DEBUG
0057 #define DBG(x...) printf(x)
0058 #else
0059 #define DBG(x...)
0060 #endif
0061
0062 #define BD_CHAN_EN (1<<BD_CHAN_EN_BIT)
0063 #define BD_CHAN_ID (0x3<<BD_CHAN_ID_BIT)
0064 #define BD_CHAN_TYPE (0x3<<BD_CHAN_TYPE_BIT)
0065 #define BD_CHAN_TYPE_DMA (0x1<<BD_CHAN_TYPE_BIT)
0066 #define BD_CHAN_BDCNT (0xffff<<BD_CHAN_BDCNT_BIT)
0067 #define BD_CHAN_EN_BIT 31
0068 #define BD_CHAN_ID_BIT 22
0069 #define BD_CHAN_TYPE_BIT 20
0070 #define BD_CHAN_BDCNT_BIT 0
0071
0072 #define BD_DATA_EN (0x1<<BD_DATA_EN_BIT)
0073 #define BD_DATA_IE (0x1<<BD_DATA_IE_BIT)
0074 #define BD_DATA_DR (0x1<<BD_DATA_DR_BIT)
0075 #define BD_DATA_BE (0x1<<BD_DATA_BE_BIT)
0076 #define BD_DATA_TYPE (0x3<<BD_DATA_TYPE_BIT)
0077 #define BD_DATA_TYPE_DATA (0x0<<BD_DATA_TYPE_BIT)
0078 #define BD_DATA_ER (0x1<<BD_DATA_ER_BIT)
0079 #define BD_DATA_LEN (0xffff<<BD_DATA_LEN_BIT)
0080 #define BD_DATA_EN_BIT 31
0081 #define BD_DATA_IE_BIT 30
0082 #define BD_DATA_DR_BIT 29
0083 #define BD_DATA_BE_BIT 28
0084 #define BD_DATA_TYPE_BIT 20
0085 #define BD_DATA_ER_BIT 19
0086 #define BD_DATA_LEN_BIT 0
0087
0088 #define DMACTRL_SAFE (0x1<<DMACTRL_SAFE_BIT)
0089 #define DMACTRL_WCLEAR (0x1fff<<DMACTRL_ERR_BIT)
0090 #define DMACTRL_ERR (0x1f<<DMACTRL_ERR_BIT)
0091 #define DMACTRL_CHIRQ (0xff<<DMACTRL_CHIRQ_BIT)
0092 #define DMACTRL_ERR (0x1f<<DMACTRL_ERR_BIT)
0093 #define DMACTRL_NUMCH (0x7<<DMACTRL_NUMCH_BIT)
0094 #define DMACTRL_DIS (0x1<<DMACTRL_DIS_BIT)
0095 #define DMACTRL_IE (0x1<<DMACTRL_IE_BIT)
0096 #define DMACTRL_ACT (0x1<<DMACTRL_ACT_BIT)
0097 #define DMACTRL_EN (0x1<<DMACTRL_EN_BIT)
0098
0099 #define DMACTRL_SAFE_BIT 31
0100 #define DMACTRL_CHIRQ_BIT 12
0101 #define DMACTRL_ERR_BIT 7
0102 #define DMACTRL_NUMCH_BIT 4
0103 #define DMACTRL_DIS_BIT 2
0104 #define DMACTRL_IE_BIT 1
0105 #define DMACTRL_ACT_BIT 3
0106 #define DMACTRL_EN_BIT 0
0107
0108
0109 #define MAX_DMA_CHANS 8
0110
0111
0112 #define MAX_DMA_TRANSFER_SIZE (0x10000*4)
0113
0114
0115 #define MAX_DMA_DATA 128
0116
0117
0118 #define BD_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (unsigned int)(val))
0119
0120 #define BD_READ(addr) grlib_read_uncached32((unsigned long)(addr))
0121 #define REG_WRITE(addr, val) (*(volatile unsigned int *)(addr) = (unsigned int)(val))
0122 #define REG_READ(addr) (*(volatile unsigned int *)(addr))
0123
0124
0125
0126
0127 struct grpci2_bd_chan {
0128 volatile unsigned int ctrl;
0129 volatile unsigned int nchan;
0130 volatile unsigned int nbd;
0131 volatile unsigned int res;
0132 };
0133
0134
0135
0136
0137 struct grpci2_bd_data {
0138 volatile unsigned int ctrl;
0139 volatile unsigned int pci_adr;
0140 volatile unsigned int ahb_adr;
0141 volatile unsigned int next;
0142 };
0143
0144
0145
0146
0147
0148 struct grpci2dma_regs {
0149 volatile unsigned int dma_ctrl;
0150 volatile unsigned int dma_bdbase;
0151 volatile unsigned int dma_chact;
0152 };
0153
0154 #define DEVNAME_LEN 11
0155
0156
0157
0158 struct grpci2dma_priv {
0159
0160 struct grpci2dma_regs *regs;
0161 char devname[DEVNAME_LEN];
0162
0163
0164 struct {
0165
0166
0167
0168 struct grpci2_bd_chan * ptr;
0169
0170 int allocated;
0171
0172
0173
0174 struct grpci2_bd_data * lastdata;
0175
0176 int active;
0177
0178
0179
0180
0181 grpci2dma_isr_t isr;
0182 void * isr_arg;
0183
0184
0185 rtems_id sem;
0186 } channel[MAX_DMA_CHANS];
0187
0188
0189 int nchans;
0190
0191
0192 int nactive;
0193
0194
0195
0196 int isr_registered;
0197
0198
0199 void (*isr_register)( void (*isr)(void*), void * arg);
0200
0201
0202 SPIN_DECLARE(devlock);
0203 };
0204
0205
0206 rtems_id grpci2dma_sem;
0207
0208
0209
0210
0211
0212 STATIC int grpci2dma_channel_list_add(struct grpci2_bd_chan * list,
0213 struct grpci2_bd_chan * chan);
0214 STATIC int grpci2dma_channel_list_remove(struct grpci2_bd_chan * chan);
0215 STATIC int grpci2dma_data_list_add(struct grpci2_bd_chan * chan,
0216 struct grpci2_bd_data * data, struct grpci2_bd_data * last_chan_data);
0217 STATIC int grpci2dma_data_list_remove(struct grpci2_bd_chan * chan,
0218 struct grpci2_bd_data * data);
0219 STATIC int grpci2dma_channel_list_foreach(struct grpci2_bd_chan * chan,
0220 int func( struct grpci2_bd_chan * chan), int maxindex);
0221 STATIC int grpci2dma_data_list_foreach(struct grpci2_bd_data * data,
0222 int func( struct grpci2_bd_data * data), int maxindex);
0223
0224
0225 STATIC INLINE int grpci2dma_ctrl_init(void);
0226 STATIC INLINE int grpci2dma_ctrl_start(struct grpci2_bd_chan * chan);
0227 STATIC INLINE int grpci2dma_ctrl_stop(void);
0228 STATIC INLINE int grpci2dma_ctrl_resume(void);
0229 STATIC INLINE unsigned int grpci2dma_ctrl_status(void);
0230 STATIC INLINE unsigned int grpci2dma_ctrl_base(void);
0231 STATIC INLINE unsigned int grpci2dma_ctrl_active(void);
0232 STATIC INLINE int grpci2dma_ctrl_numch_set(int numch);
0233 STATIC INLINE int grpci2dma_ctrl_interrupt_status(void);
0234 STATIC INLINE int grpci2dma_ctrl_interrupt_enable(void);
0235 STATIC INLINE int grpci2dma_ctrl_interrupt_disable(void);
0236 STATIC INLINE int grpci2dma_ctrl_interrupt_clear(void);
0237
0238
0239 STATIC int grpci2dma_channel_bd_init(struct grpci2_bd_chan * chan);
0240 STATIC int grpci2dma_data_bd_init(struct grpci2_bd_data * data,
0241 uint32_t pci_adr, uint32_t ahb_adr, int dir, int endianness,
0242 int size, struct grpci2_bd_data * next);
0243 STATIC int grpci2dma_channel_bd_enable(struct grpci2_bd_chan * chan,
0244 unsigned int options);
0245 STATIC int grpci2dma_channel_bd_disable(struct grpci2_bd_chan * chan);
0246 STATIC void grpci2dma_channel_bd_set_cid(struct grpci2_bd_chan * chan,
0247 int cid);
0248 STATIC int grpci2dma_channel_bd_get_cid(struct grpci2_bd_chan * chan);
0249 STATIC int grpci2dma_data_bd_status(struct grpci2_bd_data *data);
0250 STATIC int grpci2dma_data_bd_disable(struct grpci2_bd_data *desc);
0251 STATIC int grpci2dma_data_bd_interrupt_enable(struct grpci2_bd_data * data);
0252 STATIC struct grpci2_bd_data * grpci2dma_channel_bd_get_data(
0253 struct grpci2_bd_chan * chan);
0254 STATIC void grpci2dma_channel_bd_set_data(struct grpci2_bd_chan * chan,
0255 struct grpci2_bd_data * data);
0256 STATIC struct grpci2_bd_chan * grpci2dma_channel_bd_get_next(
0257 struct grpci2_bd_chan * chan);
0258 STATIC struct grpci2_bd_data * grpci2dma_data_bd_get_next(
0259 struct grpci2_bd_data * data);
0260 STATIC void grpci2dma_channel_bd_set_next(struct grpci2_bd_chan * chan,
0261 struct grpci2_bd_chan * next);
0262 STATIC void grpci2dma_data_bd_set_next(struct grpci2_bd_data * data,
0263 struct grpci2_bd_data * next);
0264
0265
0266 STATIC int grpci2dma_channel_open(struct grpci2_bd_chan * chan, int cid);
0267 STATIC int grpci2dma_channel_free_id(void);
0268 STATIC struct grpci2_bd_chan * grpci2dma_channel_get_active_list(void);
0269 STATIC int grpci2dma_channel_start(int chan_no, int options);
0270 STATIC int grpci2dma_channel_stop(int chan_no);
0271 STATIC int grpci2dma_channel_push(int chan_no, void *dataptr, int index,
0272 int ndata);
0273 STATIC int grpci2dma_channel_close(int chan_no);
0274 STATIC int grpci2dma_channel_isr_unregister(int chan_no);
0275
0276
0277 STATIC void grpci2dma_isr(void *arg);
0278
0279
0280 int grpci2dma_init(void * regs,
0281 void isr_register( void (*isr)(void*), void * arg));
0282
0283
0284 #ifdef DEBUG
0285 STATIC int grpci2dma_channel_print(struct grpci2_bd_chan * chan);
0286 STATIC int grpci2dma_data_print(struct grpci2_bd_data * data);
0287 #endif
0288
0289 static struct grpci2dma_priv *grpci2dmapriv = NULL;
0290
0291
0292
0293
0294 #define ALIGNED __attribute__((aligned(GRPCI2DMA_BD_DATA_ALIGN)))
0295 static ALIGNED struct grpci2_bd_data disabled_data = {
0296 0,
0297 0,
0298 0,
0299 0
0300 };
0301 #define DISABLED_DESCRIPTOR (&disabled_data)
0302
0303
0304
0305
0306
0307
0308
0309 STATIC int grpci2dma_channel_list_add(struct grpci2_bd_chan * list,
0310 struct grpci2_bd_chan * chan)
0311 {
0312 DBG("Adding channel (0x%08x) to GRPCI2 DMA driver\n", (unsigned int) chan);
0313
0314
0315 if (list == chan) {
0316
0317 return GRPCI2DMA_ERR_OK;
0318 } else {
0319
0320 struct grpci2_bd_chan * nchan = grpci2dma_channel_bd_get_next(list);
0321
0322 grpci2dma_channel_bd_set_next(chan,nchan);
0323
0324 grpci2dma_channel_bd_set_next(list, chan);
0325 return GRPCI2DMA_ERR_OK;
0326 }
0327 }
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337 STATIC int grpci2dma_channel_list_remove(struct grpci2_bd_chan * chan)
0338 {
0339 DBG("Removing channel (0x%08x) from GRPCI2 DMA driver\n",
0340 (unsigned int) chan);
0341
0342
0343 struct grpci2_bd_chan * nchan = grpci2dma_channel_bd_get_next(chan);
0344 if (nchan != chan){
0345
0346
0347
0348
0349
0350 struct grpci2_bd_chan * new_first_chan = nchan;
0351 struct grpci2_bd_chan * curr_chan;
0352 int i=1;
0353 while((nchan != chan) && (i<MAX_DMA_CHANS)){
0354 curr_chan = nchan;
0355 nchan = grpci2dma_channel_bd_get_next(curr_chan);
0356 i++;
0357 }
0358 if (nchan != chan) {
0359 DBG("Maximum DMA channels exceeded. Maybe corrupted?\n");
0360 return GRPCI2DMA_ERR_ERROR;
0361 } else {
0362
0363 grpci2dma_channel_bd_set_next(curr_chan, new_first_chan);
0364 return GRPCI2DMA_ERR_OK;
0365 }
0366 }else{
0367
0368 return GRPCI2DMA_ERR_OK;
0369 }
0370 }
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382 STATIC int grpci2dma_data_list_add(struct grpci2_bd_chan * chan,
0383 struct grpci2_bd_data * data, struct grpci2_bd_data * last_chan_data)
0384 {
0385 DBG("Adding data (0x%08x) to channel (0x%08x)\n",
0386 (unsigned int) data, (unsigned int) chan);
0387
0388
0389
0390 struct grpci2_bd_data * first_data = grpci2dma_channel_bd_get_data(chan);
0391 if (first_data == NULL) {
0392
0393 DBG("Channel not pointing to disabled descpriptor\n");
0394 return GRPCI2DMA_ERR_ERROR;
0395 } else if (first_data == DISABLED_DESCRIPTOR){
0396
0397 grpci2dma_channel_bd_set_data(chan, data);
0398 return GRPCI2DMA_ERR_OK;
0399 } else {
0400
0401
0402 grpci2dma_data_bd_set_next(last_chan_data, data);
0403
0404
0405 first_data = grpci2dma_channel_bd_get_data(chan);
0406 if (first_data == DISABLED_DESCRIPTOR){
0407 grpci2dma_channel_bd_set_data(chan, data);
0408 }
0409 return GRPCI2DMA_ERR_OK;
0410 }
0411 }
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427 UNUSED STATIC int grpci2dma_data_list_remove(struct grpci2_bd_chan * chan,
0428 struct grpci2_bd_data * data)
0429 {
0430 DBG("Removing data (0x%08x) from channel (0x%08x)\n",
0431 (unsigned int) data, (unsigned int) chan);
0432
0433
0434
0435 struct grpci2_bd_data * first_data = grpci2dma_channel_bd_get_data(chan);
0436 if (first_data == NULL) {
0437
0438 DBG("Channel not pointing to disabled descpriptor\n");
0439 return GRPCI2DMA_ERR_ERROR;
0440 } else if (first_data == DISABLED_DESCRIPTOR){
0441
0442 DBG("No data to detach.\n");
0443 return GRPCI2DMA_ERR_NOTFOUND;
0444 } else {
0445
0446 if (first_data == data) {
0447
0448 struct grpci2_bd_data *current = first_data;
0449 struct grpci2_bd_data *next = grpci2dma_data_bd_get_next(current);
0450 if (next != DISABLED_DESCRIPTOR){
0451
0452
0453 grpci2dma_channel_bd_set_data(chan, next);
0454
0455 grpci2dma_data_bd_set_next(data, DISABLED_DESCRIPTOR);
0456 return GRPCI2DMA_ERR_OK;
0457 }else{
0458
0459
0460 grpci2dma_channel_bd_set_data(chan, DISABLED_DESCRIPTOR);
0461
0462 grpci2dma_data_bd_set_next(data, DISABLED_DESCRIPTOR);
0463 return GRPCI2DMA_ERR_OK;
0464 }
0465 } else {
0466
0467 struct grpci2_bd_data * current = first_data;
0468 struct grpci2_bd_data * next = grpci2dma_data_bd_get_next(current);
0469 while( (next != data) && (next != DISABLED_DESCRIPTOR) &&
0470 (next != NULL)){
0471 current = next;
0472 next = grpci2dma_data_bd_get_next(current);
0473 }
0474 if (next != data) {
0475 DBG("Maximum DMA data exceeded. Maybe corrupted?\n");
0476 return GRPCI2DMA_ERR_NOTFOUND;
0477 } else {
0478
0479 next = grpci2dma_data_bd_get_next(data);
0480 grpci2dma_data_bd_set_next(current, next);
0481
0482 grpci2dma_data_bd_set_next(data, DISABLED_DESCRIPTOR);
0483 return GRPCI2DMA_ERR_OK;
0484 }
0485 }
0486 }
0487 }
0488
0489
0490
0491 UNUSED STATIC int grpci2dma_channel_list_foreach(
0492 struct grpci2_bd_chan * first_chan,
0493 int func( struct grpci2_bd_chan * chan), int maxindex)
0494 {
0495 if (maxindex <= 0) return 0;
0496 if (first_chan == NULL) {
0497
0498 return 0;
0499 } else {
0500
0501
0502
0503
0504 int i=0;
0505 int ret;
0506 struct grpci2_bd_chan * curr_chan = first_chan;
0507 struct grpci2_bd_chan * nchan;
0508 do{
0509 if (curr_chan == NULL) return GRPCI2DMA_ERR_WRONGPTR;
0510 ret = func(curr_chan);
0511 if (ret < 0){
0512
0513 return ret;
0514 }
0515 nchan = grpci2dma_channel_bd_get_next(curr_chan);
0516 curr_chan = nchan;
0517 i++;
0518 }while((curr_chan != first_chan) && (i < maxindex));
0519 }
0520 return 0;
0521 }
0522
0523
0524
0525 STATIC int grpci2dma_data_list_foreach(struct grpci2_bd_data * first_data,
0526 int func( struct grpci2_bd_data * data), int maxindex)
0527 {
0528 if (maxindex <= 0) return 0;
0529 if (first_data == NULL) return GRPCI2DMA_ERR_WRONGPTR;
0530
0531
0532
0533
0534 int i=0;
0535 int ret;
0536 struct grpci2_bd_data * curr_data = first_data;
0537 struct grpci2_bd_data * ndata;
0538 while((curr_data != DISABLED_DESCRIPTOR) && (i < maxindex)){
0539 if (curr_data == NULL) return GRPCI2DMA_ERR_WRONGPTR;
0540 ret = func(curr_data);
0541 if (ret < 0){
0542
0543 return ret;
0544 }
0545 ndata = grpci2dma_data_bd_get_next(curr_data);
0546 curr_data = ndata;
0547 i++;
0548 }
0549 return 0;
0550 }
0551
0552
0553
0554
0555
0556
0557
0558 STATIC INLINE int grpci2dma_ctrl_init()
0559 {
0560 struct grpci2dma_priv *priv = grpci2dmapriv;
0561
0562
0563 REG_WRITE(&priv->regs->dma_ctrl, 0|DMACTRL_SAFE|DMACTRL_CHIRQ|DMACTRL_ERR);
0564
0565
0566 REG_WRITE(&priv->regs->dma_bdbase, 0);
0567
0568
0569 REG_WRITE(&priv->regs->dma_chact, 0);
0570
0571 return 0;
0572 }
0573
0574
0575
0576 STATIC INLINE int grpci2dma_ctrl_stop( void )
0577 {
0578 struct grpci2dma_priv *priv = grpci2dmapriv;
0579
0580
0581 unsigned int ctrl = REG_READ(&priv->regs->dma_ctrl);
0582 REG_WRITE(&priv->regs->dma_ctrl, (ctrl & ~(DMACTRL_WCLEAR | DMACTRL_EN)) |
0583 DMACTRL_DIS);
0584
0585 return 0;
0586 }
0587
0588
0589 STATIC INLINE int grpci2dma_ctrl_start( struct grpci2_bd_chan * chan)
0590 {
0591 struct grpci2dma_priv *priv = grpci2dmapriv;
0592
0593
0594 REG_WRITE(&priv->regs->dma_bdbase, (unsigned int) chan);
0595
0596
0597 unsigned int ctrl = REG_READ(&priv->regs->dma_ctrl);
0598 REG_WRITE(&priv->regs->dma_ctrl, (ctrl & ~(DMACTRL_WCLEAR | DMACTRL_DIS)) |
0599 DMACTRL_EN);
0600
0601 return 0;
0602 }
0603
0604
0605 STATIC INLINE int grpci2dma_ctrl_resume( void )
0606 {
0607 struct grpci2dma_priv *priv = grpci2dmapriv;
0608
0609
0610 unsigned int ctrl = REG_READ(&priv->regs->dma_ctrl);
0611 REG_WRITE(&priv->regs->dma_ctrl, (ctrl & ~(DMACTRL_WCLEAR | DMACTRL_DIS)) |
0612 DMACTRL_EN);
0613
0614 return 0;
0615 }
0616
0617
0618 STATIC INLINE int grpci2dma_ctrl_interrupt_status(void)
0619 {
0620 struct grpci2dma_priv *priv = grpci2dmapriv;
0621
0622 unsigned int ctrl = REG_READ(&priv->regs->dma_ctrl);
0623 return (ctrl & DMACTRL_IE);
0624 }
0625
0626
0627 STATIC INLINE int grpci2dma_ctrl_interrupt_enable(void)
0628 {
0629 struct grpci2dma_priv *priv = grpci2dmapriv;
0630
0631 unsigned int ctrl = REG_READ(&priv->regs->dma_ctrl);
0632 if (ctrl & DMACTRL_IE){
0633
0634 return 0;
0635 }
0636
0637
0638 ctrl = ctrl | (DMACTRL_CHIRQ | DMACTRL_ERR);
0639
0640
0641 ctrl = ctrl | DMACTRL_IE;
0642
0643 REG_WRITE(&priv->regs->dma_ctrl, ctrl );
0644 return 0;
0645 }
0646
0647
0648 STATIC INLINE int grpci2dma_ctrl_interrupt_disable(void)
0649 {
0650 struct grpci2dma_priv *priv = grpci2dmapriv;
0651
0652 unsigned int ctrl = REG_READ(&priv->regs->dma_ctrl);
0653 if ((ctrl & DMACTRL_IE) == 0){
0654
0655 return 0;
0656 }
0657
0658
0659 ctrl = ctrl | (DMACTRL_CHIRQ | DMACTRL_ERR);
0660
0661
0662 ctrl = ctrl & ~(DMACTRL_IE);
0663
0664 REG_WRITE(&priv->regs->dma_ctrl, ctrl );
0665 return 0;
0666 }
0667
0668
0669 STATIC INLINE int grpci2dma_ctrl_interrupt_clear(void)
0670 {
0671 struct grpci2dma_priv *priv = grpci2dmapriv;
0672
0673 unsigned int ctrl = REG_READ(&priv->regs->dma_ctrl);
0674 REG_WRITE(&priv->regs->dma_ctrl, (ctrl | DMACTRL_ERR | DMACTRL_CHIRQ));
0675 return 0;
0676 }
0677
0678 STATIC INLINE unsigned int grpci2dma_ctrl_status()
0679 {
0680 struct grpci2dma_priv *priv = grpci2dmapriv;
0681
0682
0683 return (REG_READ(&priv->regs->dma_ctrl));
0684 }
0685
0686 STATIC INLINE unsigned int grpci2dma_ctrl_base()
0687 {
0688 struct grpci2dma_priv *priv = grpci2dmapriv;
0689
0690
0691 return (REG_READ(&priv->regs->dma_bdbase));
0692 }
0693
0694 UNUSED STATIC INLINE unsigned int grpci2dma_ctrl_active()
0695 {
0696 struct grpci2dma_priv *priv = grpci2dmapriv;
0697
0698
0699 return (REG_READ(&priv->regs->dma_chact));
0700 }
0701
0702
0703 STATIC INLINE int grpci2dma_ctrl_numch_set(int numch)
0704 {
0705 struct grpci2dma_priv *priv = grpci2dmapriv;
0706
0707 unsigned int ctrl = REG_READ(&priv->regs->dma_ctrl);
0708
0709
0710 ctrl = (ctrl & ~(DMACTRL_NUMCH));
0711
0712
0713 ctrl = (ctrl | ( (numch << DMACTRL_NUMCH_BIT) & DMACTRL_NUMCH));
0714
0715 REG_WRITE(&priv->regs->dma_ctrl, ctrl & ~(DMACTRL_WCLEAR));
0716 return 0;
0717 }
0718
0719
0720
0721
0722
0723 STATIC int grpci2dma_data_bd_init(struct grpci2_bd_data * data,
0724 uint32_t pci_adr, uint32_t ahb_adr, int dir, int endianness, int size,
0725 struct grpci2_bd_data * next)
0726 {
0727 BD_WRITE(&data->ctrl, 0 |
0728 (BD_DATA_EN) |
0729 (BD_DATA_TYPE_DATA) |
0730 (dir == GRPCI2DMA_AHBTOPCI? BD_DATA_DR:0) |
0731 (endianness == GRPCI2DMA_LITTLEENDIAN? BD_DATA_BE:0) |
0732 ( (size << BD_DATA_LEN_BIT) & BD_DATA_LEN )
0733 );
0734 BD_WRITE(&data->pci_adr, pci_adr);
0735 BD_WRITE(&data->ahb_adr, ahb_adr);
0736 BD_WRITE(&data->next, (unsigned int) next);
0737 return 0;
0738 }
0739
0740 STATIC int grpci2dma_channel_bd_init(struct grpci2_bd_chan * chan)
0741 {
0742 BD_WRITE(&chan->ctrl, 0 | BD_CHAN_TYPE_DMA | BD_CHAN_EN);
0743 BD_WRITE(&chan->nchan, (unsigned int) chan);
0744 BD_WRITE(&chan->nbd, (unsigned int) DISABLED_DESCRIPTOR);
0745 return 0;
0746 }
0747
0748
0749
0750
0751
0752
0753 STATIC int grpci2dma_channel_bd_enable(struct grpci2_bd_chan * chan,
0754 unsigned int options)
0755 {
0756 unsigned int ctrl = BD_READ(&chan->ctrl);
0757 ctrl = (ctrl & ~(BD_CHAN_BDCNT));
0758 BD_WRITE(&chan->ctrl, (ctrl | BD_CHAN_EN |
0759 ( (options << BD_CHAN_BDCNT_BIT) & BD_CHAN_BDCNT)));
0760 return 0;
0761 }
0762
0763
0764
0765 STATIC int grpci2dma_channel_bd_disable(struct grpci2_bd_chan * chan)
0766 {
0767 unsigned int ctrl = BD_READ(&chan->ctrl);
0768 BD_WRITE(&chan->ctrl, (ctrl & ~(BD_CHAN_EN)));
0769 return 0;
0770 }
0771
0772
0773
0774 UNUSED STATIC int grpci2dma_channel_bd_get_cid(struct grpci2_bd_chan * chan)
0775 {
0776
0777 unsigned ctrl = BD_READ(&chan->ctrl);
0778 unsigned cid = (ctrl & (BD_CHAN_ID)) >> BD_CHAN_ID_BIT;
0779 return cid;
0780 }
0781
0782
0783 STATIC void grpci2dma_channel_bd_set_cid(struct grpci2_bd_chan * chan, int cid)
0784 {
0785
0786 unsigned ctrl = BD_READ(&chan->ctrl);
0787 ctrl = (ctrl & ~(BD_CHAN_ID)) | ((cid << BD_CHAN_ID_BIT) & BD_CHAN_ID);
0788 BD_WRITE(&chan->ctrl,ctrl);
0789 return;
0790 }
0791
0792
0793 UNUSED STATIC int grpci2dma_data_bd_disable(struct grpci2_bd_data *desc)
0794 {
0795 BD_WRITE(&desc->ctrl,0);
0796 return 0;
0797 }
0798
0799
0800 STATIC int grpci2dma_data_bd_status(struct grpci2_bd_data *desc)
0801 {
0802 int status = BD_READ(&desc->ctrl);
0803 if (status & BD_DATA_ER) {
0804 return GRPCI2DMA_BD_STATUS_ERR;
0805 }else if (status & BD_DATA_EN) {
0806 return GRPCI2DMA_BD_STATUS_ENABLED;
0807 }else {
0808 return GRPCI2DMA_BD_STATUS_DISABLED;
0809 }
0810 return GRPCI2DMA_BD_STATUS_ERR;
0811 }
0812
0813
0814 STATIC int grpci2dma_data_bd_interrupt_enable(struct grpci2_bd_data * data)
0815 {
0816 unsigned int ctrl = BD_READ(&data->ctrl);
0817 BD_WRITE(&data->ctrl, ctrl | BD_DATA_IE);
0818 return 0;
0819 }
0820
0821
0822 STATIC struct grpci2_bd_data * grpci2dma_channel_bd_get_data(
0823 struct grpci2_bd_chan * chan)
0824 {
0825 return (struct grpci2_bd_data *) BD_READ(&chan->nbd);
0826 }
0827
0828
0829 STATIC void grpci2dma_channel_bd_set_data(struct grpci2_bd_chan * chan,
0830 struct grpci2_bd_data * data)
0831 {
0832 BD_WRITE(&chan->nbd, (unsigned int) data);
0833 }
0834
0835
0836 STATIC struct grpci2_bd_chan * grpci2dma_channel_bd_get_next(
0837 struct grpci2_bd_chan * chan)
0838 {
0839 return (struct grpci2_bd_chan *) BD_READ(&chan->nchan);
0840 }
0841
0842
0843 STATIC struct grpci2_bd_data * grpci2dma_data_bd_get_next(
0844 struct grpci2_bd_data * data)
0845 {
0846 return (struct grpci2_bd_data *) BD_READ(&data->next);
0847 }
0848
0849
0850 STATIC void grpci2dma_channel_bd_set_next(struct grpci2_bd_chan * chan,
0851 struct grpci2_bd_chan * next)
0852 {
0853 BD_WRITE(&chan->nchan,(unsigned int) next);
0854 }
0855
0856
0857 STATIC void grpci2dma_data_bd_set_next(struct grpci2_bd_data * data,
0858 struct grpci2_bd_data * next)
0859 {
0860 BD_WRITE(&data->next,(unsigned int) next);
0861 }
0862
0863
0864
0865
0866
0867 STATIC int grpci2dma_channel_open(struct grpci2_bd_chan * chan, int cid)
0868 {
0869 struct grpci2dma_priv *priv = grpci2dmapriv;
0870 int allocated = 0;
0871
0872
0873 if (chan == NULL) {
0874
0875 chan = grpci2dma_channel_new(1);
0876 allocated = 1;
0877 }else{
0878
0879 int i;
0880 for (i=0; i<MAX_DMA_CHANS; i++){
0881 if (priv->channel[i].ptr == chan){
0882 return GRPCI2DMA_ERR_WRONGPTR;
0883 }
0884 }
0885 }
0886
0887 DBG("Opening channel %d (0x%08x)\n", cid, (unsigned int) chan);
0888
0889
0890 grpci2dma_channel_bd_init(chan);
0891
0892
0893 priv->channel[cid].ptr = chan;
0894 grpci2dma_channel_bd_set_cid(chan, cid);
0895
0896
0897 priv->nchans++;
0898
0899 DBG("number of channels: %d\n", priv->nchans);
0900
0901
0902 priv->channel[cid].allocated = allocated;
0903 priv->channel[cid].active = 0;
0904
0905
0906 priv->channel[cid].lastdata = DISABLED_DESCRIPTOR;
0907
0908 return cid;
0909 }
0910
0911
0912
0913 STATIC int grpci2dma_channel_free_id()
0914 {
0915 struct grpci2dma_priv *priv = grpci2dmapriv;
0916
0917
0918 int i;
0919 for (i=0; i<MAX_DMA_CHANS; i++){
0920 if (priv->channel[i].ptr == NULL){
0921 return i;
0922 }
0923 }
0924 return GRPCI2DMA_ERR_TOOMANY;
0925 }
0926
0927
0928 STATIC struct grpci2_bd_chan * grpci2dma_channel_get_active_list()
0929 {
0930 struct grpci2dma_priv *priv = grpci2dmapriv;
0931 int i;
0932
0933 for (i=0; i< MAX_DMA_CHANS; i++){
0934 if ((priv->channel[i].ptr != NULL) && (priv->channel[i].active)){
0935 return priv->channel[i].ptr;
0936 }
0937 }
0938 return NULL;
0939 }
0940
0941
0942 STATIC int grpci2dma_channel_start(int chan_no, int options)
0943 {
0944 struct grpci2dma_priv *priv = grpci2dmapriv;
0945 struct grpci2_bd_chan *chan;
0946 SPIN_IRQFLAGS(irqflags);
0947
0948
0949 chan = priv->channel[chan_no].ptr;
0950
0951
0952 if (priv->channel[chan_no].active){
0953
0954 return GRPCI2DMA_ERR_OK;
0955 }
0956
0957
0958 unsigned int desccnt;
0959 if (options == 0){
0960
0961 desccnt = 0xffff;
0962 }else{
0963 desccnt = options & 0xffff;
0964 }
0965
0966
0967
0968
0969
0970 grpci2dma_channel_bd_enable(chan, desccnt);
0971 priv->channel[chan_no].active = 1;
0972 priv->nactive++;
0973
0974 struct grpci2_bd_chan * list = grpci2dma_channel_get_active_list();
0975 if (list == NULL){
0976
0977 list = chan;
0978 }
0979
0980 if (grpci2dma_channel_list_add(list, chan) < 0){
0981 return GRPCI2DMA_ERR_ERROR;
0982 }
0983
0984
0985 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0986 grpci2dma_ctrl_numch_set( (priv->nactive? priv->nactive -1:0));
0987
0988
0989 if (!grpci2dma_active()){
0990
0991 grpci2dma_ctrl_start(chan);
0992 }
0993 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0994
0995 DBG("Channel %d started (0x%08x)\n", chan_no, (unsigned int) chan);
0996
0997 return GRPCI2DMA_ERR_OK;
0998 }
0999
1000
1001 STATIC int grpci2dma_channel_stop(int chan_no)
1002 {
1003 struct grpci2dma_priv *priv = grpci2dmapriv;
1004 struct grpci2_bd_chan *chan;
1005 SPIN_IRQFLAGS(irqflags);
1006 int resume;
1007
1008
1009 chan = priv->channel[chan_no].ptr;
1010
1011
1012 if (!priv->channel[chan_no].active){
1013
1014 return GRPCI2DMA_ERR_OK;
1015 }
1016
1017
1018 if (grpci2dma_channel_list_remove(chan) < 0){
1019 return GRPCI2DMA_ERR_ERROR;
1020 }
1021
1022
1023 priv->channel[chan_no].active = 0;
1024 priv->nactive--;
1025
1026
1027
1028 resume = 0;
1029 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
1030 if (grpci2dma_active() && (grpci2dma_ctrl_active() == (unsigned int)chan)){
1031
1032 grpci2dma_ctrl_stop();
1033 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
1034
1035 while (grpci2dma_active()){}
1036
1037 resume = 1;
1038 }else{
1039 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
1040 }
1041
1042
1043
1044
1045
1046
1047
1048 grpci2dma_channel_bd_set_next(chan, chan);
1049
1050
1051
1052
1053
1054 grpci2dma_channel_bd_disable(chan);
1055
1056
1057 grpci2dma_channel_bd_set_data(chan, DISABLED_DESCRIPTOR);
1058
1059 DBG("Channel %d stoped (0x%08x)\n", chan_no, (unsigned int) chan);
1060
1061
1062 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
1063 grpci2dma_ctrl_numch_set( (priv->nactive? priv->nactive -1:0));
1064
1065
1066 if (resume){
1067
1068
1069
1070 if (grpci2dma_ctrl_active() == (unsigned int) chan){
1071
1072
1073 int i;
1074 for (i=0; i<MAX_DMA_CHANS; i++){
1075 if (priv->channel[i].active){
1076 grpci2dma_ctrl_start(priv->channel[i].ptr);
1077 break;
1078 }
1079 }
1080 }else{
1081
1082
1083
1084
1085
1086
1087 grpci2dma_ctrl_resume();
1088 }
1089 }
1090 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
1091
1092 return GRPCI2DMA_ERR_OK;
1093 }
1094
1095 STATIC int grpci2dma_channel_push(int chan_no, void *dataptr, int index,
1096 int ndata)
1097 {
1098 struct grpci2dma_priv *priv = grpci2dmapriv;
1099 struct grpci2_bd_chan * chan;
1100 struct grpci2_bd_data * data = dataptr;
1101
1102
1103 chan = priv->channel[chan_no].ptr;
1104
1105 DBG("Pushing %d data (starting at 0x%08x) to channel %d (0x%08x)\n",
1106 ndata, (unsigned int) &data[index], chan_no, (unsigned int) chan);
1107
1108
1109 struct grpci2_bd_data * last_added = priv->channel[chan_no].lastdata;
1110
1111
1112 grpci2dma_data_list_add(chan, &data[index], last_added);
1113
1114
1115 priv->channel[chan_no].lastdata = &data[index + ndata-1];
1116
1117 return GRPCI2DMA_ERR_OK;
1118 }
1119
1120 STATIC int grpci2dma_channel_close(int chan_no)
1121 {
1122 struct grpci2dma_priv *priv = grpci2dmapriv;
1123 struct grpci2_bd_chan * chan;
1124
1125
1126 chan = priv->channel[chan_no].ptr;
1127
1128 DBG("Closing channel %d (0x%08x)\n", chan_no, (unsigned int) chan);
1129
1130
1131 if (grpci2dma_channel_stop(chan_no) != GRPCI2DMA_ERR_OK ){
1132 DBG("Cannot stop channel!.\n");
1133 return GRPCI2DMA_ERR_STOPDMA;
1134 }
1135
1136
1137 grpci2dma_channel_isr_unregister(chan_no);
1138
1139
1140 priv->channel[chan_no].ptr = NULL;
1141
1142
1143 priv->channel[chan_no].isr = NULL;
1144 priv->channel[chan_no].isr_arg = NULL;
1145
1146
1147 if (priv->channel[chan_no].allocated){
1148 grpci2dma_channel_delete((void *)chan);
1149 }
1150
1151
1152 priv->nchans--;
1153
1154 DBG("number of channels: %d\n", priv->nchans);
1155
1156
1157 return GRPCI2DMA_ERR_OK;
1158 }
1159
1160
1161 STATIC int grpci2dma_channel_isr_unregister(int chan_no)
1162 {
1163 struct grpci2dma_priv *priv = grpci2dmapriv;
1164 SPIN_IRQFLAGS(irqflags);
1165
1166
1167 priv->channel[chan_no].isr = NULL;
1168 priv->channel[chan_no].isr_arg = NULL;
1169
1170
1171 priv->isr_registered--;
1172 if(priv->isr_registered == 0){
1173
1174 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
1175 grpci2dma_ctrl_interrupt_disable();
1176 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
1177 (priv->isr_register)( NULL, NULL);
1178 }
1179
1180
1181 return GRPCI2DMA_ERR_OK;
1182 }
1183
1184
1185
1186
1187
1188
1189 STATIC void grpci2dma_isr(void *arg)
1190 {
1191 struct grpci2dma_priv *priv = arg;
1192 SPIN_ISR_IRQFLAGS(irqflags);
1193 unsigned int ctrl = grpci2dma_ctrl_status();
1194
1195 SPIN_LOCK(&priv->devlock, irqflags);
1196 grpci2dma_ctrl_interrupt_clear();
1197 SPIN_UNLOCK(&priv->devlock, irqflags);
1198 unsigned int sts = (ctrl & DMACTRL_CHIRQ) >> DMACTRL_CHIRQ_BIT;
1199 unsigned int errsts = (ctrl & DMACTRL_ERR);
1200
1201
1202 if(errsts){
1203
1204
1205
1206
1207
1208
1209 struct grpci2_bd_chan * chan =
1210 (struct grpci2_bd_chan *) grpci2dma_ctrl_base();
1211
1212 if ((BD_READ(&chan->ctrl) & BD_CHAN_TYPE) != BD_CHAN_TYPE_DMA){
1213
1214
1215 chan = (struct grpci2_bd_chan *) grpci2dma_ctrl_active();
1216 }
1217 int i;
1218 for (i=0; i<MAX_DMA_CHANS; i++){
1219 if (chan == priv->channel[i].ptr){
1220
1221 if (priv->channel[i].isr != NULL){
1222 (priv->channel[i].isr)(priv->channel[i].isr_arg,i,errsts);
1223 }else{
1224 printk("Unhandled GRPCI2 DMA error interrupt, sts:0x%02x\n", errsts);
1225 }
1226 break;
1227 }
1228 }
1229 if (i == MAX_DMA_CHANS){
1230 printk("Unhandled GRPCI2 DMA error interrupt , sts:0x%02x\n", errsts);
1231 }
1232 }
1233
1234
1235 int cid=0;
1236
1237 while(sts){
1238
1239 if(sts & 0x1){
1240
1241 if (priv->channel[cid].isr != NULL){
1242 (priv->channel[cid].isr)(
1243 priv->channel[cid].isr_arg, cid, errsts);
1244 }else{
1245 printk("Unhandled GRPCI2 DMA interrupt in channel %d, sts:0x%02x\n", cid, 0);
1246 }
1247 }
1248
1249 sts = sts >> 1;
1250 cid++;
1251 }
1252 }
1253
1254
1255
1256
1257 #ifdef DEBUG
1258 STATIC int grpci2dma_channel_print(struct grpci2_bd_chan * chan)
1259 {
1260 printf(" GRPCI2 DMA channel descriptor\n");
1261 printf(" 0x%08x DMA channel control 0x%08x\n", (unsigned int) chan, chan->ctrl);
1262 printf(" 31 en 0x%01x Channel descriptor enable.\n", (chan->ctrl >> 31) & (0x1));
1263 printf(" 24:22 cid 0x%01x Channel ID.\n", (chan->ctrl >> 22) & (0x7));
1264 printf(" 21:20 type 0x%01x Descriptor type. 01=DMA channel descriptor.\n", (chan->ctrl >> 20) & (0x3));
1265 printf(" 15:0 dlen 0x%04x Data descriptor count.\n", (chan->ctrl >> 0) & (0xffff));
1266 printf("\n");
1267 printf(" 0x%08x Next DMA channel 0x%08x\n", (unsigned int) &(chan->nchan), chan->nchan);
1268 printf(" 31:0 nc 0x%08x Next DMA channel.\n", chan->nchan);
1269 printf("\n");
1270 printf(" 0x%08x Next data descriptor 0x%08x\n" , (unsigned int) &(chan->nbd), chan->nbd);
1271 printf(" 31:0 nd 0x%08x Next data descriptor.\n", chan->nbd);
1272 printf("\n");
1273 return 0;
1274 }
1275
1276 STATIC int grpci2dma_data_print(struct grpci2_bd_data * data)
1277 {
1278 printf(" GRPCI2 DMA data descriptor\n");
1279 printf(" 0x%08x DMA data control 0x%08x\n", (unsigned int) data, data->ctrl);
1280 printf(" 31 en 0x%01x Data descriptor enable.\n" , (data->ctrl >> 31) & (0x1));
1281 printf(" 30 ie 0x%01x Interrupt generation enable.\n" , (data->ctrl >> 30) & (0x1));
1282 printf(" 29 dr 0x%01x Tranfer direction.\n" , (data->ctrl >> 29) & (0x1));
1283 printf(" 28 be 0x%01x Bus endianess.\n" , (data->ctrl >> 28) & (0x1));
1284 printf(" 21:20 type 0x%01x Descriptor type. 00=DMA data descriptor.\n" , (data->ctrl >> 20) & (0x3));
1285 printf(" 19 er 0x%01x Error status.\n" , (data->ctrl >> 19) & (0x1));
1286 printf(" 15:0 len 0x%04x Transfer lenght (in words) - 1.\n" , (data->ctrl >> 0) & (0xffff));
1287 printf("\n");
1288 printf(" 0x%08x 32-bit PCI start address 0x%08x\n" , (unsigned int) &(data->pci_adr), data->pci_adr);
1289 printf(" 31:0 pa 0x%08x PCI address.\n" , data->pci_adr);
1290 printf("\n");
1291 printf(" 0x%08x 32-bit AHB start address 0x%08x\n" , (unsigned int) &(data->ahb_adr), data->ahb_adr);
1292 printf(" 31:0 aa 0x%08x AHB address.\n" , data->ahb_adr);
1293 printf("\n");
1294 printf(" 0x%08x Next data descriptor 0x%08x\n" , (unsigned int) &(data->next), data->next);
1295 printf(" 31:0 nd 0x%08x Next data descriptor.\n" , data->next);
1296 printf("\n");
1297 return 0;
1298 }
1299 #endif
1300
1301
1302
1303
1304 void * grpci2dma_channel_new(int number)
1305 {
1306
1307 unsigned int * orig_ptr = (unsigned int *) grlib_malloc(
1308 (GRPCI2DMA_BD_CHAN_SIZE)*number + GRPCI2DMA_BD_CHAN_ALIGN);
1309 if (orig_ptr == NULL) return NULL;
1310
1311
1312 unsigned int aligned_ptr = (
1313 ((unsigned int) orig_ptr + GRPCI2DMA_BD_CHAN_ALIGN) &
1314 ~(GRPCI2DMA_BD_CHAN_ALIGN - 1));
1315
1316
1317 unsigned int ** tmp_ptr =
1318 (unsigned int **) (aligned_ptr - sizeof(orig_ptr));
1319 *tmp_ptr= orig_ptr;
1320
1321
1322 return (void *) aligned_ptr;
1323 }
1324
1325 void grpci2dma_channel_delete(void * chan)
1326 {
1327
1328 unsigned int * orig_ptr;
1329 unsigned int ** tmp_ptr = (unsigned int **) (chan - sizeof(orig_ptr));
1330 orig_ptr = *tmp_ptr;
1331
1332
1333 free(orig_ptr);
1334 }
1335
1336 void * grpci2dma_data_new(int number)
1337 {
1338
1339 unsigned int * orig_ptr = (unsigned int *) grlib_malloc(
1340 (GRPCI2DMA_BD_DATA_SIZE)*number + GRPCI2DMA_BD_DATA_ALIGN);
1341 if (orig_ptr == NULL) return NULL;
1342
1343
1344 unsigned int aligned_ptr = (
1345 ((unsigned int) orig_ptr + GRPCI2DMA_BD_DATA_ALIGN) &
1346 ~(GRPCI2DMA_BD_DATA_ALIGN - 1));
1347
1348
1349 unsigned int ** tmp_ptr =
1350 (unsigned int **) (aligned_ptr - sizeof(orig_ptr));
1351 *tmp_ptr= orig_ptr;
1352
1353
1354 return (void *) aligned_ptr;
1355 }
1356
1357 void grpci2dma_data_delete(void * data)
1358 {
1359
1360 unsigned int * orig_ptr;
1361 unsigned int ** tmp_ptr = (unsigned int **) (data - sizeof(orig_ptr));
1362 orig_ptr = *tmp_ptr;
1363
1364
1365 free(orig_ptr);
1366 }
1367
1368
1369
1370
1371
1372
1373
1374 int grpci2dma_init(
1375 void * regs, void isr_register( void (*isr)(void*), void * arg))
1376 {
1377 struct grpci2dma_priv *priv;
1378 int i;
1379
1380 DBG("Registering GRPCI2 DMA driver with arg: 0x%08x\n",
1381 (unsigned int) regs);
1382
1383
1384 if (grpci2dmapriv) {
1385 DBG("Driver only supports one PCI DMA core\n");
1386 return DRVMGR_FAIL;
1387 }
1388
1389
1390 if (rtems_semaphore_create(rtems_build_name('G', 'P', '2', 'D'), 1,
1391 RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | \
1392 RTEMS_NO_INHERIT_PRIORITY | RTEMS_LOCAL | \
1393 RTEMS_NO_PRIORITY_CEILING, 0, &grpci2dma_sem) != RTEMS_SUCCESSFUL)
1394 return -1;
1395
1396
1397 priv = grlib_calloc(1, sizeof(*priv));
1398 if (priv == NULL)
1399 return DRVMGR_NOMEM;
1400
1401 priv->regs = regs;
1402 strncpy(&priv->devname[0], "grpci2dma0", DEVNAME_LEN);
1403
1404
1405 SPIN_INIT(&priv->devlock, priv->devname);
1406
1407
1408 for (i=0; i<MAX_DMA_CHANS; i++){
1409
1410 priv->channel[i].sem = RTEMS_ID_NONE;
1411 }
1412
1413
1414 grpci2dmapriv = priv;
1415
1416
1417 grpci2dma_ctrl_init();
1418
1419
1420 priv->isr_register = isr_register;
1421
1422
1423
1424
1425 grpci2dma_ctrl_stop();
1426
1427 return DRVMGR_OK;
1428 }
1429
1430
1431 int grpci2dma_isr_register(int chan_no, grpci2dma_isr_t dmaisr, void *data)
1432 {
1433 struct grpci2dma_priv *priv = grpci2dmapriv;
1434 SPIN_IRQFLAGS(irqflags);
1435
1436 if (!priv){
1437
1438 return GRPCI2DMA_ERR_NOINIT;
1439 }
1440
1441
1442 if (dmaisr == NULL){
1443
1444 return GRPCI2DMA_ERR_WRONGPTR;
1445 }
1446
1447
1448 if ((chan_no < 0 ) || (chan_no >= MAX_DMA_CHANS)) {
1449
1450 return GRPCI2DMA_ERR_WRONGPTR;
1451 }
1452
1453
1454 if (priv->channel[chan_no].ptr == NULL){
1455
1456 return GRPCI2DMA_ERR_NOTFOUND;
1457 }
1458
1459
1460 if (rtems_semaphore_obtain(grpci2dma_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1461 != RTEMS_SUCCESSFUL){
1462 return GRPCI2DMA_ERR_ERROR;
1463 }
1464
1465
1466 if (rtems_semaphore_obtain(priv->channel[chan_no].sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1467 != RTEMS_SUCCESSFUL){
1468 rtems_semaphore_release(grpci2dma_sem);
1469 return GRPCI2DMA_ERR_ERROR;
1470 }
1471
1472
1473 priv->channel[chan_no].isr_arg = data;
1474 priv->channel[chan_no].isr = dmaisr;
1475
1476
1477 if(priv->isr_registered == 0){
1478 (priv->isr_register)( grpci2dma_isr, (void *) priv);
1479
1480 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
1481 grpci2dma_ctrl_interrupt_enable();
1482 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
1483 }
1484 priv->isr_registered++;
1485
1486
1487 rtems_semaphore_release(priv->channel[chan_no].sem);
1488
1489
1490 rtems_semaphore_release(grpci2dma_sem);
1491
1492 return GRPCI2DMA_ERR_OK;
1493 }
1494
1495
1496 int grpci2dma_isr_unregister(int chan_no)
1497 {
1498 struct grpci2dma_priv *priv = grpci2dmapriv;
1499 int ret;
1500
1501 if (!priv){
1502
1503 return GRPCI2DMA_ERR_NOINIT;
1504 }
1505
1506
1507 if ((chan_no < 0 ) || (chan_no >= MAX_DMA_CHANS)) {
1508
1509 return GRPCI2DMA_ERR_WRONGPTR;
1510 }
1511
1512
1513 if (priv->channel[chan_no].ptr == NULL){
1514
1515 return GRPCI2DMA_ERR_NOTFOUND;
1516 }
1517
1518
1519 if (priv->channel[chan_no].isr == NULL){
1520
1521 return GRPCI2DMA_ERR_OK;
1522 }
1523
1524
1525 if (rtems_semaphore_obtain(grpci2dma_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1526 != RTEMS_SUCCESSFUL){
1527 return GRPCI2DMA_ERR_ERROR;
1528 }
1529
1530
1531 if (rtems_semaphore_obtain(priv->channel[chan_no].sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1532 != RTEMS_SUCCESSFUL){
1533 rtems_semaphore_release(grpci2dma_sem);
1534 return GRPCI2DMA_ERR_ERROR;
1535 }
1536
1537
1538 ret = grpci2dma_channel_isr_unregister(chan_no);
1539
1540
1541 rtems_semaphore_release(priv->channel[chan_no].sem);
1542
1543
1544 rtems_semaphore_release(grpci2dma_sem);
1545
1546 return ret;
1547 }
1548
1549 int grpci2dma_open(void * chanptr)
1550 {
1551 struct grpci2dma_priv *priv = grpci2dmapriv;
1552 int cid;
1553 int ret;
1554
1555 if (!priv){
1556
1557 return GRPCI2DMA_ERR_NOINIT;
1558 }
1559
1560
1561 if (((unsigned int ) chanptr) & (GRPCI2DMA_BD_CHAN_ALIGN-1)) {
1562
1563 return GRPCI2DMA_ERR_WRONGPTR;
1564 }
1565
1566
1567 if (rtems_semaphore_obtain(grpci2dma_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1568 != RTEMS_SUCCESSFUL){
1569 return GRPCI2DMA_ERR_ERROR;
1570 }
1571
1572
1573 cid = grpci2dma_channel_free_id();
1574 if (cid < 0 ){
1575 rtems_semaphore_release(grpci2dma_sem);
1576 return GRPCI2DMA_ERR_TOOMANY;
1577 }
1578
1579
1580 ret = grpci2dma_channel_open((struct grpci2_bd_chan *) chanptr, cid);
1581
1582
1583 if (ret >= 0){
1584 if (rtems_semaphore_create(
1585 rtems_build_name('P', 'D', '0', '0' + cid), 1,
1586 RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | \
1587 RTEMS_NO_INHERIT_PRIORITY | RTEMS_LOCAL | \
1588 RTEMS_NO_PRIORITY_CEILING, 0, &priv->channel[cid].sem
1589 ) != RTEMS_SUCCESSFUL) {
1590 priv->channel[cid].sem = RTEMS_ID_NONE;
1591 rtems_semaphore_release(grpci2dma_sem);
1592 return GRPCI2DMA_ERR_ERROR;
1593 }
1594 }
1595
1596
1597 rtems_semaphore_release(grpci2dma_sem);
1598
1599
1600 return ret;
1601 }
1602
1603 int grpci2dma_close(int chan_no)
1604 {
1605 struct grpci2dma_priv *priv = grpci2dmapriv;
1606 int ret;
1607
1608 if (!priv){
1609
1610 return GRPCI2DMA_ERR_NOINIT;
1611 }
1612
1613
1614 if ((chan_no < 0) || (chan_no >= MAX_DMA_CHANS)){
1615
1616 return GRPCI2DMA_ERR_WRONGPTR;
1617 }
1618
1619
1620 if (priv->channel[chan_no].ptr == NULL){
1621
1622 return GRPCI2DMA_ERR_NOTFOUND;
1623 }
1624
1625
1626 if (rtems_semaphore_obtain(grpci2dma_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1627 != RTEMS_SUCCESSFUL){
1628 return GRPCI2DMA_ERR_ERROR;
1629 }
1630
1631
1632 if (rtems_semaphore_obtain(priv->channel[chan_no].sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1633 != RTEMS_SUCCESSFUL){
1634 rtems_semaphore_release(grpci2dma_sem);
1635 return GRPCI2DMA_ERR_ERROR;
1636 }
1637
1638
1639 ret = grpci2dma_channel_close(chan_no);
1640
1641
1642 rtems_semaphore_release(priv->channel[chan_no].sem);
1643
1644
1645 if (ret == GRPCI2DMA_ERR_OK){
1646 if (rtems_semaphore_delete(priv->channel[chan_no].sem)
1647 != RTEMS_SUCCESSFUL){
1648
1649 rtems_semaphore_release(grpci2dma_sem);
1650 return GRPCI2DMA_ERR_ERROR;
1651 }
1652 }
1653
1654
1655 rtems_semaphore_release(grpci2dma_sem);
1656
1657 return ret;
1658 }
1659
1660
1661 int grpci2dma_prepare(
1662 uint32_t pci_start, uint32_t ahb_start, int dir, int endianness,
1663 int size, void * dataptr, int index, int ndata, int transfer_size)
1664 {
1665 struct grpci2_bd_data * data = dataptr;
1666
1667
1668 if ((data == NULL) ||
1669 (((unsigned int ) data) & (GRPCI2DMA_BD_DATA_ALIGN-1))){
1670 return GRPCI2DMA_ERR_WRONGPTR;
1671 }
1672
1673
1674 int maxdata = ndata - index;
1675 if ((maxdata < 1) || (index < 0)){
1676
1677 return GRPCI2DMA_ERR_WRONGPTR;
1678 }
1679
1680
1681 if ( (transfer_size < 0) ||
1682 (transfer_size > MAX_DMA_TRANSFER_SIZE) ||
1683 (transfer_size%4 != 0) ) {
1684 return GRPCI2DMA_ERR_WRONGPTR;
1685 }
1686 if (transfer_size == 0){
1687 transfer_size = MAX_DMA_TRANSFER_SIZE;
1688 }
1689
1690
1691 if ( (size <=0) || (size % 4 != 0)){
1692 return GRPCI2DMA_ERR_WRONGPTR;
1693 }
1694
1695
1696 int words = size/4;
1697 int blocksize = transfer_size/4;
1698 int datacnt = words/blocksize + (words%blocksize != 0? 1: 0);
1699
1700 if (datacnt > maxdata) {
1701 return GRPCI2DMA_ERR_TOOMANY;
1702 }
1703
1704
1705 int i;
1706 uint32_t pci_adr;
1707 uint32_t ahb_adr;
1708 int remaining=words;
1709 int datasize;
1710 struct grpci2_bd_data * next;
1711 for (i=0; i<datacnt; i++){
1712
1713 pci_adr = pci_start + i*blocksize;
1714 ahb_adr = ahb_start + i*blocksize;
1715
1716 if (remaining >= blocksize){
1717 datasize = blocksize - 1;
1718 remaining -= blocksize;
1719 } else {
1720 datasize = remaining -1;
1721 remaining = 0;
1722 }
1723
1724 if (i == datacnt - 1){
1725
1726 next = DISABLED_DESCRIPTOR;
1727 }else{
1728 next = &data[i+index+1];
1729 }
1730
1731 grpci2dma_data_bd_init(&data[i+index], pci_adr, ahb_adr, dir, endianness, datasize, next);
1732 }
1733
1734 return datacnt;
1735 }
1736
1737 int grpci2dma_status(void *dataptr, int index, int ndata)
1738 {
1739 struct grpci2_bd_data * data = dataptr;
1740 int i;
1741
1742
1743 if ((data == NULL) ||
1744 (((unsigned int ) data) & (GRPCI2DMA_BD_DATA_ALIGN-1))){
1745 return GRPCI2DMA_ERR_WRONGPTR;
1746 }
1747
1748
1749 int maxdata = ndata - index;
1750 if ((maxdata < 1) || (index < 0)){
1751
1752 return GRPCI2DMA_ERR_WRONGPTR;
1753 }
1754
1755
1756 int status;
1757 for (i=0; i< maxdata; i++){
1758 status = grpci2dma_data_bd_status(&data[i+index]);
1759 if (status == GRPCI2DMA_BD_STATUS_ERR){
1760
1761 return status;
1762 } else if (status == GRPCI2DMA_BD_STATUS_ENABLED){
1763
1764 return status;
1765 }
1766 }
1767
1768
1769 return status;
1770 }
1771
1772 int grpci2dma_print(int chan_no)
1773 {
1774 struct grpci2dma_priv *priv = grpci2dmapriv;
1775 struct grpci2_bd_chan * chan;
1776
1777 if (!priv){
1778
1779 DBG("DMA not initialized.\n");
1780 return GRPCI2DMA_ERR_NOINIT;
1781 }
1782
1783 if ( (chan_no < 0) || (chan_no >= MAX_DMA_CHANS )){
1784
1785 return GRPCI2DMA_ERR_WRONGPTR;
1786 }
1787
1788 chan = priv->channel[chan_no].ptr;
1789 if (chan == NULL) {
1790 return GRPCI2DMA_ERR_WRONGPTR;
1791 }
1792
1793 #ifdef DEBUG
1794
1795 grpci2dma_channel_print(chan);
1796
1797
1798 struct grpci2_bd_data * first_data = (struct grpci2_bd_data *) BD_READ(&chan->nbd);
1799
1800
1801 grpci2dma_data_list_foreach(first_data, grpci2dma_data_print, MAX_DMA_DATA);
1802 #endif
1803 return GRPCI2DMA_ERR_OK;
1804 }
1805
1806 int grpci2dma_print_bd(void * dataptr)
1807 {
1808 struct grpci2dma_priv *priv = grpci2dmapriv;
1809 struct grpci2_bd_data * data = (struct grpci2_bd_data *) dataptr;
1810
1811 if (!priv){
1812
1813 DBG("DMA not initialized.\n");
1814 return GRPCI2DMA_ERR_NOINIT;
1815 }
1816
1817 if ( data == NULL ){
1818
1819 return GRPCI2DMA_ERR_WRONGPTR;
1820 }
1821
1822 #ifdef DEBUG
1823
1824 grpci2dma_data_list_foreach(data, grpci2dma_data_print, MAX_DMA_DATA);
1825 #endif
1826 return GRPCI2DMA_ERR_OK;
1827 }
1828
1829 int grpci2dma_interrupt_enable(
1830 void *dataptr, int index, int maxindex, int options)
1831 {
1832 struct grpci2_bd_data * data = dataptr;
1833 struct grpci2dma_priv *priv = grpci2dmapriv;
1834 SPIN_IRQFLAGS(irqflags);
1835
1836 if (!priv){
1837
1838 return GRPCI2DMA_ERR_NOINIT;
1839 }
1840
1841
1842 if ((data == NULL) ||
1843 (((unsigned int ) data) & (GRPCI2DMA_BD_DATA_ALIGN-1))){
1844 return GRPCI2DMA_ERR_WRONGPTR;
1845 }
1846
1847
1848 if ((index < 0) || (maxindex < 1) || (index >= maxindex)){
1849
1850 return GRPCI2DMA_ERR_WRONGPTR;
1851 }
1852
1853 if (options & GRPCI2DMA_OPTIONS_ALL){
1854
1855 if (grpci2dma_data_list_foreach(
1856 &data[index],
1857 grpci2dma_data_bd_interrupt_enable, maxindex -index)){
1858 return GRPCI2DMA_ERR_ERROR;
1859 }
1860 }else{
1861
1862 grpci2dma_data_bd_interrupt_enable(&data[index]);
1863 }
1864
1865
1866 if (grpci2dma_ctrl_interrupt_status()==0){
1867 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
1868 grpci2dma_ctrl_interrupt_enable();
1869 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
1870 }
1871
1872 DBG("Interrupts enabled for data (0x%08x), index:%d, maxindex:%d, %s.\n",
1873 (unsigned int) data, index, maxindex,
1874 (options & GRPCI2DMA_OPTIONS_ALL)? "ALL":"ONE" );
1875
1876 return GRPCI2DMA_ERR_OK;
1877 }
1878
1879 int grpci2dma_push(int chan_no, void *dataptr, int index, int ndata)
1880 {
1881 struct grpci2dma_priv *priv = grpci2dmapriv;
1882 SPIN_IRQFLAGS(irqflags);
1883 int ret;
1884
1885 if (!priv){
1886
1887 return GRPCI2DMA_ERR_NOINIT;
1888 }
1889
1890
1891 if ((dataptr == NULL) ||
1892 (((unsigned int ) dataptr) & (GRPCI2DMA_BD_DATA_ALIGN-1))){
1893 return GRPCI2DMA_ERR_WRONGPTR;
1894 }
1895
1896
1897 if ((ndata < 1) || (index < 0)){
1898
1899 return GRPCI2DMA_ERR_WRONGPTR;
1900 }
1901
1902
1903 if ( (chan_no < 0) || (chan_no >= MAX_DMA_CHANS )){
1904
1905 return GRPCI2DMA_ERR_WRONGPTR;
1906 }
1907
1908
1909 if (priv->channel[chan_no].ptr == NULL){
1910
1911 return GRPCI2DMA_ERR_NOTFOUND;
1912 }
1913
1914
1915 if (rtems_semaphore_obtain(priv->channel[chan_no].sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1916 != RTEMS_SUCCESSFUL){
1917 return GRPCI2DMA_ERR_ERROR;
1918 }
1919
1920
1921 ret = grpci2dma_channel_push(chan_no, dataptr, index, ndata);
1922
1923 if (ret != GRPCI2DMA_ERR_OK){
1924
1925 rtems_semaphore_release(priv->channel[chan_no].sem);
1926 return ret;
1927 }
1928
1929
1930 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
1931 if ((!grpci2dma_active()) && (priv->channel[chan_no].active)){
1932 grpci2dma_ctrl_start(priv->channel[chan_no].ptr);
1933 }
1934 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
1935
1936
1937 rtems_semaphore_release(priv->channel[chan_no].sem);
1938
1939 return ret;
1940 }
1941
1942
1943 int grpci2dma_start(int chan_no, int options)
1944 {
1945 struct grpci2dma_priv *priv = grpci2dmapriv;
1946 int ret;
1947
1948 if (!priv){
1949
1950 return GRPCI2DMA_ERR_NOINIT;
1951 }
1952
1953 if ((chan_no < 0 ) || (chan_no >= MAX_DMA_CHANS )) {
1954
1955 return GRPCI2DMA_ERR_WRONGPTR;
1956 }
1957
1958 if ( options < 0 ) {
1959
1960 return GRPCI2DMA_ERR_WRONGPTR;
1961 }
1962
1963
1964 if (priv->channel[chan_no].ptr == NULL){
1965
1966 return GRPCI2DMA_ERR_NOTFOUND;
1967 }
1968
1969
1970 if (rtems_semaphore_obtain(grpci2dma_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1971 != RTEMS_SUCCESSFUL){
1972 return GRPCI2DMA_ERR_ERROR;
1973 }
1974
1975
1976 if (rtems_semaphore_obtain(priv->channel[chan_no].sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1977 != RTEMS_SUCCESSFUL){
1978 rtems_semaphore_release(grpci2dma_sem);
1979 return GRPCI2DMA_ERR_ERROR;
1980 }
1981
1982
1983 ret = grpci2dma_channel_start(chan_no, options);
1984
1985
1986 rtems_semaphore_release(priv->channel[chan_no].sem);
1987
1988
1989 rtems_semaphore_release(grpci2dma_sem);
1990
1991 return ret;
1992 }
1993
1994
1995 int grpci2dma_stop(int chan_no)
1996 {
1997 struct grpci2dma_priv *priv = grpci2dmapriv;
1998 int ret;
1999
2000 if (!priv){
2001
2002 return GRPCI2DMA_ERR_NOINIT;
2003 }
2004
2005 if ((chan_no < 0 ) || (chan_no >= MAX_DMA_CHANS)) {
2006
2007 return GRPCI2DMA_ERR_WRONGPTR;
2008 }
2009
2010
2011 if (priv->channel[chan_no].ptr == NULL){
2012
2013 return GRPCI2DMA_ERR_NOTFOUND;
2014 }
2015
2016
2017 if (rtems_semaphore_obtain(grpci2dma_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
2018 != RTEMS_SUCCESSFUL){
2019 return GRPCI2DMA_ERR_ERROR;
2020 }
2021
2022
2023 if (rtems_semaphore_obtain(priv->channel[chan_no].sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
2024 != RTEMS_SUCCESSFUL){
2025 rtems_semaphore_release(grpci2dma_sem);
2026 return GRPCI2DMA_ERR_ERROR;
2027 }
2028
2029
2030 ret = grpci2dma_channel_stop(chan_no);
2031
2032
2033 rtems_semaphore_release(priv->channel[chan_no].sem);
2034
2035
2036 rtems_semaphore_release(grpci2dma_sem);
2037
2038 return ret;
2039 }
2040
2041 int grpci2dma_active()
2042 {
2043 return ((grpci2dma_ctrl_status()) & DMACTRL_ACT) >> DMACTRL_ACT_BIT;
2044 }
2045