File indexing completed on 2025-05-11 08:24:05
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 #include <rtems.h>
0031 #include <stdlib.h>
0032 #include <stdio.h>
0033 #include <string.h>
0034
0035 #include <grlib/gr1553b.h>
0036 #include <grlib/gr1553rt.h>
0037
0038 #include <drvmgr/drvmgr.h>
0039 #include <grlib/ambapp_bus.h>
0040
0041 #include <grlib/grlib_impl.h>
0042
0043 #define GR1553RT_WRITE_MEM(adr, val) *(volatile uint32_t *)(adr) = (uint32_t)(val)
0044 #define GR1553RT_READ_MEM(adr) (*(volatile uint32_t *)(adr))
0045
0046 #define GR1553RT_WRITE_REG(adr, val) *(volatile uint32_t *)(adr) = (uint32_t)(val)
0047 #define GR1553RT_READ_REG(adr) (*(volatile uint32_t *)(adr))
0048
0049
0050 struct gr1553rt_sw_bd {
0051 unsigned short this_next;
0052 unsigned char listid;
0053 char unused;
0054 } __attribute__((packed));
0055
0056
0057 struct gr1553rt_subadr {
0058
0059 unsigned char rxlistid;
0060
0061 unsigned char txlistid;
0062 };
0063
0064 struct gr1553rt_irqerr {
0065 gr1553rt_irqerr_t func;
0066 void *data;
0067 };
0068
0069 struct gr1553rt_irqmc {
0070 gr1553rt_irqmc_t func;
0071 void *data;
0072 };
0073
0074 struct gr1553rt_irq {
0075 gr1553rt_irq_t func;
0076 void *data;
0077 };
0078
0079 struct gr1553rt_priv {
0080
0081 struct gr1553b_regs *regs;
0082
0083
0084 int started;
0085 struct gr1553rt_cfg cfg;
0086 SPIN_DECLARE(devlock);
0087
0088
0089 struct drvmgr_dev **pdev;
0090
0091
0092 struct gr1553rt_subadr subadrs[32];
0093
0094
0095
0096
0097 #if (RTBD_MAX == 0)
0098 struct gr1553rt_sw_bd *swbds;
0099 #else
0100 struct gr1553rt_sw_bd swbds[RTBD_MAX];
0101 #endif
0102
0103
0104 unsigned short swbd_free;
0105 int swbd_free_cnt;
0106
0107
0108 void *satab_buffer;
0109 struct gr1553rt_sa *sas_cpu;
0110 struct gr1553rt_sa *sas_hw;
0111
0112
0113 void *bd_buffer;
0114 int bds_cnt;
0115 struct gr1553rt_bd *bds_cpu;
0116 struct gr1553rt_bd *bds_hw;
0117
0118
0119
0120 void *evlog_buffer;
0121 unsigned int *evlog_cpu_next;
0122 unsigned int *evlog_cpu_base;
0123 unsigned int *evlog_cpu_end;
0124 unsigned int *evlog_hw_base;
0125
0126
0127 struct gr1553rt_list *lists[RTLISTID_MAX];
0128
0129
0130 struct gr1553rt_irq irq_rx[32];
0131 struct gr1553rt_irq irq_tx[32];
0132
0133
0134 struct gr1553rt_irqerr irq_err;
0135
0136
0137 struct gr1553rt_irqmc irq_mc;
0138 };
0139
0140 void gr1553rt_sw_init(struct gr1553rt_priv *priv);
0141 void gr1553rt_sw_free(struct gr1553rt_priv *priv);
0142 void gr1553rt_isr(void *data);
0143
0144
0145
0146
0147
0148
0149 static int gr1553rt_list_reg(struct gr1553rt_list *list)
0150 {
0151 struct gr1553rt_priv *priv = list->rt;
0152 int i;
0153
0154
0155 for ( i=0; i<RTLISTID_MAX; i++) {
0156 if ( priv->lists[i] == NULL ) {
0157 priv->lists[i] = list;
0158 list->listid = i;
0159 return i;
0160 }
0161 }
0162
0163
0164 list->listid = -1;
0165
0166 return -1;
0167 }
0168
0169
0170 static void gr1553rt_list_unreg(struct gr1553rt_list *list)
0171 {
0172 struct gr1553rt_priv *priv = list->rt;
0173
0174 priv->lists[list->listid] = NULL;
0175 list->listid = -1;
0176 }
0177
0178 static int gr1553rt_bdid(void *rt, struct gr1553rt_sw_bd *bd)
0179 {
0180 struct gr1553rt_priv *priv = rt;
0181
0182 unsigned short index;
0183
0184
0185 index = ((unsigned int)bd - (unsigned int)&priv->swbds[0]) /
0186 sizeof(struct gr1553rt_sw_bd);
0187
0188 return index;
0189 }
0190
0191 static void gr1553rt_bd_alloc_init(void *rt, int count)
0192 {
0193 struct gr1553rt_priv *priv = rt;
0194 int i;
0195
0196 for (i=0; i<count-1; i++) {
0197 priv->swbds[i].this_next = i+1;
0198 }
0199 priv->swbds[count-1].this_next = 0xffff;
0200 priv->swbd_free = 0;
0201 priv->swbd_free_cnt = count;
0202 }
0203
0204
0205 static int gr1553rt_bd_alloc(void *rt, struct gr1553rt_sw_bd **bd, int cnt)
0206 {
0207 struct gr1553rt_priv *priv = rt;
0208 struct gr1553rt_sw_bd *curr;
0209 int i;
0210
0211 if ((priv->swbd_free_cnt < cnt) || (cnt <= 0)) {
0212 *bd = NULL;
0213 return -1;
0214 }
0215
0216 *bd = &priv->swbds[priv->swbd_free];
0217 curr = &priv->swbds[priv->swbd_free];
0218 for (i=0; i<cnt; i++) {
0219 if ( i != 0) {
0220 curr = &priv->swbds[curr->this_next];
0221 }
0222 if ( curr->this_next == 0xffff ) {
0223 *bd = NULL;
0224 return -1;
0225 }
0226 }
0227 priv->swbd_free = curr->this_next;
0228 priv->swbd_free_cnt -= cnt;
0229 curr->this_next = 0xffff;
0230
0231 return 0;
0232 }
0233
0234 #if 0
0235 static void gr1553rt_bd_free(void *rt, struct gr1553rt_sw_bd *bd)
0236 {
0237 struct gr1553rt_priv *priv = rt;
0238 unsigned short index;
0239
0240
0241 index = gr1553rt_bdid(priv, bd);
0242
0243
0244 bd->this_next = priv->swbd_free;
0245 priv->swbd_free = index;
0246 priv->swbd_free_cnt++;
0247 }
0248 #endif
0249
0250 int gr1553rt_list_init
0251 (
0252 void *rt,
0253 struct gr1553rt_list **plist,
0254 struct gr1553rt_list_cfg *cfg
0255 )
0256 {
0257 struct gr1553rt_priv *priv = rt;
0258 size_t size;
0259 int i, malloc_used;
0260 struct gr1553rt_sw_bd *swbd;
0261 unsigned short index;
0262 struct gr1553rt_list *list;
0263
0264
0265
0266
0267
0268
0269
0270 malloc_used = 0;
0271 list = *plist;
0272 if ( list == NULL ) {
0273
0274 size = sizeof(*list) +
0275 (cfg->bd_cnt * sizeof(list->bds[0]));
0276 list = grlib_malloc(size);
0277 if ( list == NULL )
0278 return -1;
0279 *plist = list;
0280 malloc_used = 1;
0281 }
0282
0283 list->rt = rt;
0284 list->subadr = -1;
0285 list->listid = gr1553rt_list_reg(list);
0286 if ( list->listid == -1 ) {
0287 if (malloc_used)
0288 free(list);
0289 return -2;
0290 }
0291 list->cfg = cfg;
0292 list->bd_cnt = cfg->bd_cnt;
0293
0294
0295 if ( gr1553rt_bd_alloc(rt, &swbd, list->bd_cnt) ) {
0296 gr1553rt_list_unreg(list);
0297 if (malloc_used)
0298 free(list);
0299 return -3;
0300 }
0301
0302
0303 index = gr1553rt_bdid(rt, swbd);
0304 list->bds[0] = index;
0305 for (i=1; i<list->bd_cnt; i++) {
0306 list->bds[i] = priv->swbds[list->bds[i-1]].this_next;
0307 }
0308
0309
0310
0311
0312
0313 for (i=0; i<list->bd_cnt; i++) {
0314 priv->swbds[list->bds[i]].this_next = i;
0315 }
0316
0317 return 0;
0318 }
0319
0320 int gr1553rt_bd_init(
0321 struct gr1553rt_list *list,
0322 unsigned short entry_no,
0323 unsigned int flags,
0324 uint16_t *dptr,
0325 unsigned short next
0326 )
0327 {
0328 struct gr1553rt_priv *priv;
0329 unsigned short bdid;
0330 struct gr1553rt_bd *bd;
0331 unsigned int nextbd, dataptr;
0332 SPIN_IRQFLAGS(irqflags);
0333
0334 if ( entry_no >= list->bd_cnt )
0335 return -1;
0336
0337
0338 bdid = list->bds[entry_no];
0339 priv = list->rt;
0340 bd = &priv->bds_cpu[bdid];
0341
0342 if ( next == 0xfffe ) {
0343 next = entry_no + 1;
0344 if ( next >= list->bd_cnt )
0345 next = 0;
0346 }
0347
0348
0349
0350
0351 if ( next >= 0xffff ) {
0352 nextbd = 0x3;
0353 } else if ( next >= list->bd_cnt ) {
0354 return -1;
0355 } else {
0356 bdid = list->bds[next];
0357 nextbd = (unsigned int)&priv->bds_hw[bdid];
0358 }
0359
0360 dataptr = (unsigned int)dptr;
0361 if ( dataptr & 1 ) {
0362
0363 dataptr &= ~1;
0364 drvmgr_translate(
0365 *priv->pdev,
0366 CPUMEM_TO_DMA,
0367 (void *)dataptr,
0368 (void **)&dataptr
0369 );
0370 }
0371
0372
0373 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0374 bd->ctrl = flags & GR1553RT_BD_FLAGS_IRQEN;
0375 bd->dptr = (unsigned int)dptr;
0376 bd->next = nextbd;
0377 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0378
0379 return 0;
0380 }
0381
0382 int gr1553rt_bd_update(
0383 struct gr1553rt_list *list,
0384 int entry_no,
0385 unsigned int *status,
0386 uint16_t **dptr
0387 )
0388 {
0389 struct gr1553rt_priv *priv;
0390 unsigned short bdid;
0391 struct gr1553rt_bd *bd;
0392 unsigned int tmp, dataptr;
0393 SPIN_IRQFLAGS(irqflags);
0394
0395 if ( entry_no >= list->bd_cnt )
0396 return -1;
0397
0398
0399 bdid = list->bds[entry_no];
0400 priv = list->rt;
0401 bd = &priv->bds_cpu[bdid];
0402
0403
0404 if ( dptr && (dataptr=(unsigned int)*dptr) ) {
0405 if ( dataptr & 1 ) {
0406
0407
0408
0409 dataptr &= ~1;
0410 drvmgr_translate(
0411 *priv->pdev,
0412 CPUMEM_TO_DMA,
0413 (void *)dataptr,
0414 (void **)&dataptr
0415 );
0416 }
0417 }
0418
0419
0420 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0421
0422 if ( status ) {
0423 tmp = bd->ctrl;
0424 if ( *status ) {
0425 bd->ctrl = *status;
0426 }
0427 *status = tmp;
0428 }
0429
0430 if ( dptr ) {
0431 tmp = bd->dptr;
0432 if ( dataptr ) {
0433 bd->dptr = dataptr;
0434 }
0435 *dptr = (uint16_t *)tmp;
0436 }
0437 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0438
0439 return 0;
0440 }
0441
0442 int gr1553rt_irq_err
0443 (
0444 void *rt,
0445 gr1553rt_irqerr_t func,
0446 void *data
0447 )
0448 {
0449 struct gr1553rt_priv *priv = rt;
0450 SPIN_IRQFLAGS(irqflags);
0451
0452 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0453 priv->irq_err.func = func;
0454 priv->irq_err.data = data;
0455 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0456
0457 return 0;
0458 }
0459
0460 int gr1553rt_irq_mc
0461 (
0462 void *rt,
0463 gr1553rt_irqmc_t func,
0464 void *data
0465 )
0466 {
0467 struct gr1553rt_priv *priv = rt;
0468 SPIN_IRQFLAGS(irqflags);
0469
0470 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0471 priv->irq_mc.func = func;
0472 priv->irq_mc.data = data;
0473 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0474
0475 return 0;
0476 }
0477
0478 int gr1553rt_irq_sa
0479 (
0480 void *rt,
0481 int subadr,
0482 int tx,
0483 gr1553rt_irq_t func,
0484 void *data
0485 )
0486 {
0487 struct gr1553rt_priv *priv = rt;
0488 SPIN_IRQFLAGS(irqflags);
0489
0490 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0491 if ( tx ) {
0492 priv->irq_tx[subadr].func = func;
0493 priv->irq_tx[subadr].data = data;
0494 } else {
0495 priv->irq_rx[subadr].func = func;
0496 priv->irq_rx[subadr].data = data;
0497 }
0498 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0499
0500 return 0;
0501 }
0502
0503
0504 void gr1553rt_isr(void *data)
0505 {
0506 struct gr1553rt_priv *priv = data;
0507 unsigned int firstirq, lastpos;
0508 int index;
0509 unsigned int *last, *curr, entry, hwbd;
0510 int type, samc, mcode, subadr;
0511 int listid;
0512 struct gr1553rt_irq *pisr, isr;
0513 struct gr1553rt_irqerr isrerr;
0514 struct gr1553rt_irqmc isrmc;
0515 unsigned int irq;
0516 SPIN_ISR_IRQFLAGS(irqflags);
0517
0518
0519
0520
0521
0522 irq = priv->regs->irq &
0523 (GR1553B_IRQ_RTTE|GR1553B_IRQ_RTD|GR1553B_IRQ_RTEV);
0524 if ( irq == 0 )
0525 return;
0526
0527 firstirq = priv->regs->rt_evirq;
0528 priv->regs->irq = irq;
0529 lastpos = priv->regs->rt_evlog;
0530
0531
0532 if ( lastpos == firstirq )
0533 return;
0534
0535 if ( irq & (GR1553B_IRQ_RTTE|GR1553B_IRQ_RTD) ) {
0536
0537 SPIN_LOCK(&priv->devlock, irqflags);
0538 isrerr = priv->irq_err;
0539 SPIN_UNLOCK(&priv->devlock, irqflags);
0540 if ( isrerr.func ) {
0541 isrerr.func(irq, isrerr.data);
0542 }
0543
0544
0545
0546
0547 gr1553rt_stop(priv);
0548 }
0549
0550
0551
0552
0553
0554
0555
0556
0557 index = (firstirq - (unsigned int)priv->evlog_hw_base) /
0558 sizeof(unsigned int);
0559 curr = priv->evlog_cpu_base + index;
0560 index = (lastpos - (unsigned int)priv->evlog_hw_base) /
0561 sizeof(unsigned int);
0562 last = priv->evlog_cpu_base + index;
0563
0564 do {
0565
0566 entry = *curr;
0567
0568 if ( entry & 0x80000000 ) {
0569
0570 type = (entry >> 29) & 0x3;
0571 samc = (entry >> 24) & 0x1f;
0572 if ( (type & 0x2) == 0 ) {
0573
0574 subadr = samc;
0575 if ( type ) {
0576
0577 listid = priv->subadrs[subadr].rxlistid;
0578 hwbd = priv->sas_cpu[subadr].rxptr;
0579 pisr = &priv->irq_rx[subadr];
0580 } else {
0581
0582 listid = priv->subadrs[subadr].txlistid;
0583 hwbd = priv->sas_cpu[subadr].txptr;
0584 pisr = &priv->irq_tx[subadr];
0585 }
0586
0587 index = ((unsigned int)hwbd - (unsigned int)
0588 priv->bds_hw)/sizeof(struct gr1553rt_bd);
0589
0590
0591 SPIN_LOCK(&priv->devlock, irqflags);
0592 isr = *pisr;
0593 SPIN_UNLOCK(&priv->devlock, irqflags);
0594
0595
0596 if ( isr.func ) {
0597 isr.func(
0598 priv->lists[listid],
0599 entry,
0600 priv->swbds[index].this_next,
0601 isr.data
0602 );
0603 }
0604 } else if ( type == 0x2) {
0605
0606 mcode = samc;
0607
0608
0609 SPIN_LOCK(&priv->devlock, irqflags);
0610 isrmc = priv->irq_mc;
0611 SPIN_UNLOCK(&priv->devlock, irqflags);
0612
0613
0614 if ( isrmc.func ) {
0615 isrmc.func(
0616 mcode,
0617 entry,
0618 isrmc.data
0619 );
0620 }
0621 } else {
0622
0623 rtems_fatal_error_occurred(RTEMS_IO_ERROR);
0624 }
0625 }
0626
0627
0628 curr++;
0629 if ( curr == priv->evlog_cpu_end )
0630 curr = priv->evlog_cpu_base;
0631
0632 } while ( curr != last );
0633 }
0634
0635 int gr1553rt_indication(void *rt, int subadr, int *txeno, int *rxeno)
0636 {
0637 struct gr1553rt_priv *priv = rt;
0638 struct gr1553rt_sa *sa;
0639 unsigned int bd, index;
0640
0641
0642 if ( (subadr < 0) || (subadr > 31) )
0643 return -1;
0644
0645
0646 sa = &priv->sas_cpu[subadr];
0647
0648
0649 if ( txeno ) {
0650 bd = sa->txptr;
0651
0652 index = ((unsigned int)bd - (unsigned int)&priv->bds_hw[0]) /
0653 sizeof(struct gr1553rt_bd);
0654 *txeno = priv->swbds[index].this_next;
0655 }
0656
0657
0658 if ( rxeno ) {
0659 bd = sa->rxptr;
0660
0661 index = ((unsigned int)bd - (unsigned int)&priv->bds_hw[0]) /
0662 sizeof(struct gr1553rt_bd);
0663 *rxeno = priv->swbds[index].this_next;
0664 }
0665
0666 return 0;
0667 }
0668
0669 void gr1553rt_hw_stop(struct gr1553rt_priv *priv);
0670
0671 void gr1553rt_register(void)
0672 {
0673
0674 gr1553_register();
0675 }
0676
0677 void *gr1553rt_open(int minor)
0678 {
0679 struct drvmgr_dev **pdev = NULL;
0680 struct gr1553rt_priv *priv = NULL;
0681 struct amba_dev_info *ambadev;
0682 struct ambapp_core *pnpinfo;
0683
0684
0685 pdev = gr1553_rt_open(minor);
0686 if ( pdev == NULL )
0687 goto fail;
0688
0689 priv = grlib_calloc(1, sizeof(*priv));
0690 if ( priv == NULL )
0691 goto fail;
0692
0693
0694 priv->pdev = pdev;
0695 (*pdev)->priv = priv;
0696
0697
0698 ambadev = (struct amba_dev_info *)(*pdev)->businfo;
0699 pnpinfo = &ambadev->info;
0700 priv->regs = (struct gr1553b_regs *)pnpinfo->apb_slv->start;
0701
0702 SPIN_INIT(&priv->devlock, "gr1553rt");
0703
0704
0705
0706
0707
0708 gr1553rt_hw_stop(priv);
0709
0710
0711
0712
0713 if (drvmgr_interrupt_register(*priv->pdev, 0, "gr1553rt", gr1553rt_isr, priv))
0714 goto fail;
0715
0716 return priv;
0717
0718 fail:
0719 if ( pdev )
0720 gr1553_rt_close(pdev);
0721 if ( priv )
0722 free(priv);
0723 return NULL;
0724 }
0725
0726 void gr1553rt_close(void *rt)
0727 {
0728 struct gr1553rt_priv *priv = rt;
0729
0730 if ( priv->started ) {
0731 gr1553rt_stop(priv);
0732 }
0733
0734
0735 drvmgr_interrupt_unregister(*priv->pdev, 0, gr1553rt_isr, priv);
0736
0737
0738 gr1553rt_sw_free(priv);
0739 SPIN_FREE(&priv->devlock);
0740
0741
0742 gr1553_rt_close(priv->pdev);
0743 }
0744
0745
0746 void gr1553rt_hw_stop(struct gr1553rt_priv *priv)
0747 {
0748 uint32_t irqmask;
0749
0750
0751 GR1553RT_WRITE_REG(&priv->regs->rt_cfg, GR1553RT_KEY);
0752
0753
0754
0755
0756 GR1553RT_WRITE_REG(&priv->regs->bc_ctrl, GR1553BC_KEY | 0x0204);
0757
0758
0759 irqmask=GR1553RT_READ_REG(&priv->regs->imask);
0760 irqmask&=~(GR1553B_IRQEN_RTEVE|GR1553B_IRQEN_RTDE);
0761 GR1553RT_WRITE_REG(&priv->regs->irq, irqmask);
0762 }
0763
0764
0765 void gr1553rt_sw_free(struct gr1553rt_priv *priv)
0766 {
0767
0768 if ( (priv->cfg.evlog_buffer == NULL) && priv->evlog_buffer ) {
0769 free(priv->evlog_buffer);
0770 priv->evlog_buffer = NULL;
0771 }
0772
0773
0774 if ( (priv->cfg.bd_buffer == NULL) && priv->bd_buffer ) {
0775 free(priv->bd_buffer);
0776 priv->bd_buffer = NULL;
0777 }
0778
0779 #if (RTBD_MAX == 0)
0780 if ( priv->swbds ) {
0781 free(priv->swbds);
0782 priv->swbds = NULL;
0783 }
0784 #endif
0785
0786
0787 if ( (priv->cfg.satab_buffer == NULL) && priv->satab_buffer ) {
0788 free(priv->satab_buffer);
0789 priv->satab_buffer = NULL;
0790 }
0791 }
0792
0793 static int gr1553rt_sw_alloc(struct gr1553rt_priv *priv)
0794 {
0795 int size;
0796 int retval = 0;
0797
0798
0799 if ((unsigned int)priv->cfg.evlog_buffer & 1) {
0800
0801 priv->evlog_buffer = (void *)
0802 ((unsigned int)priv->cfg.evlog_buffer & ~0x1);
0803 priv->evlog_hw_base = (unsigned int*)priv->evlog_buffer;
0804 drvmgr_translate_check(
0805 *priv->pdev,
0806 DMAMEM_TO_CPU,
0807 (void *)priv->evlog_hw_base,
0808 (void **)&priv->evlog_cpu_base,
0809 priv->cfg.evlog_size
0810 );
0811 } else {
0812 if (priv->cfg.evlog_buffer == NULL) {
0813 priv->evlog_buffer = grlib_malloc(
0814 priv->cfg.evlog_size * 2);
0815 if (priv->evlog_buffer == NULL) {
0816 retval = -1;
0817 goto err;
0818 }
0819
0820 priv->evlog_cpu_base = (unsigned int *)
0821 (((unsigned int)priv->evlog_buffer +
0822 (priv->cfg.evlog_size-1)) & ~(priv->cfg.evlog_size-1));
0823 } else {
0824
0825 priv->evlog_buffer = priv->cfg.evlog_buffer;
0826 priv->evlog_cpu_base = (unsigned int *)priv->evlog_buffer;
0827 }
0828
0829 drvmgr_translate_check(
0830 *priv->pdev,
0831 CPUMEM_TO_DMA,
0832 (void *)priv->evlog_cpu_base,
0833 (void **)&priv->evlog_hw_base,
0834 priv->cfg.evlog_size
0835 );
0836 }
0837
0838 if ((unsigned int)priv->evlog_hw_base & (priv->cfg.evlog_size-1)) {
0839 retval = -2;
0840 goto err;
0841 }
0842 priv->evlog_cpu_end = priv->evlog_cpu_base +
0843 priv->cfg.evlog_size/sizeof(unsigned int *);
0844
0845
0846 priv->bds_cnt = priv->cfg.bd_count;
0847 size = priv->bds_cnt * sizeof(struct gr1553rt_bd);
0848 if ((unsigned int)priv->cfg.bd_buffer & 1) {
0849
0850 priv->bd_buffer = (void *)
0851 ((unsigned int)priv->cfg.bd_buffer & ~0x1);
0852 priv->bds_hw = (struct gr1553rt_bd *)priv->bd_buffer;
0853 drvmgr_translate_check(
0854 *priv->pdev,
0855 DMAMEM_TO_CPU,
0856 (void *)priv->bds_hw,
0857 (void **)&priv->bds_cpu,
0858 size
0859 );
0860 } else {
0861 if ( priv->cfg.bd_buffer == NULL ) {
0862 priv->bd_buffer = grlib_malloc(size + 0xf);
0863 if (priv->bd_buffer == NULL) {
0864 retval = -1;
0865 goto err;
0866 }
0867
0868 priv->bds_cpu = (struct gr1553rt_bd *)
0869 (((unsigned int)priv->bd_buffer + 0xf) & ~0xf);
0870 } else {
0871
0872 priv->bd_buffer = priv->cfg.bd_buffer;
0873 priv->bds_cpu = (struct gr1553rt_bd *)priv->bd_buffer;
0874 }
0875
0876
0877 drvmgr_translate_check(
0878 *priv->pdev,
0879 CPUMEM_TO_DMA,
0880 (void *)priv->bds_cpu,
0881 (void **)&priv->bds_hw,
0882 size
0883 );
0884 }
0885
0886 if ((unsigned int)priv->bds_hw & (0xf)) {
0887 retval = -2;
0888 goto err;
0889 }
0890
0891 #if (RTBD_MAX == 0)
0892
0893 priv->swbds = grlib_malloc(priv->cfg.bd_count * sizeof(*priv->swbds));
0894 if ( priv->swbds == NULL ) {
0895 retval = -1;
0896 goto err;
0897 }
0898 #endif
0899
0900
0901 if ((unsigned int)priv->cfg.satab_buffer & 1) {
0902
0903 priv->satab_buffer = (void *)
0904 ((unsigned int)priv->cfg.satab_buffer & ~0x1);
0905 priv->sas_hw = (struct gr1553rt_sa *)priv->satab_buffer;
0906
0907 drvmgr_translate_check(
0908 *priv->pdev,
0909 DMAMEM_TO_CPU,
0910 (void *)priv->sas_hw,
0911 (void **)&priv->sas_cpu,
0912 16 * 32);
0913 } else {
0914 if (priv->cfg.satab_buffer == NULL) {
0915 priv->satab_buffer = grlib_malloc((16 * 32) * 2);
0916 if (priv->satab_buffer == NULL) {
0917 retval = -1;
0918 goto err;
0919 }
0920
0921 priv->sas_cpu = (struct gr1553rt_sa *)
0922 (((unsigned int)priv->satab_buffer + 0x1ff) & ~0x1ff);
0923 } else {
0924
0925 priv->satab_buffer = priv->cfg.satab_buffer;
0926 priv->sas_cpu = (struct gr1553rt_sa *)priv->satab_buffer;
0927 }
0928
0929
0930 drvmgr_translate_check(
0931 *priv->pdev,
0932 CPUMEM_TO_DMA,
0933 (void *)priv->sas_cpu,
0934 (void **)&priv->sas_hw,
0935 16 * 32);
0936 }
0937
0938 if ((unsigned int)priv->sas_hw & (0x1ff)) {
0939 retval = -2;
0940 goto err;
0941 }
0942
0943 err:
0944 if (retval) {
0945 gr1553rt_sw_free(priv);
0946 }
0947 return retval;
0948 }
0949
0950 void gr1553rt_sw_init(struct gr1553rt_priv *priv)
0951 {
0952 int i;
0953
0954
0955 memset(priv->sas_cpu, 0, 512);
0956
0957
0958 memset(priv->bds_cpu, 0, priv->bds_cnt * 16);
0959
0960
0961 memset(priv->evlog_cpu_base, 0, priv->cfg.evlog_size);
0962
0963
0964 gr1553rt_bd_alloc_init(priv, priv->bds_cnt);
0965
0966
0967
0968
0969 for (i=0; i<32; i++) {
0970 priv->subadrs[i].rxlistid = 0xff;
0971 priv->subadrs[i].txlistid = 0xff;
0972 }
0973
0974
0975 for (i=0; i<32; i++) {
0976 priv->irq_rx[i].func = NULL;
0977 priv->irq_tx[i].data = NULL;
0978 }
0979 priv->irq_err.func = NULL;
0980 priv->irq_err.data = NULL;
0981 priv->irq_mc.func = NULL;
0982 priv->irq_mc.data = NULL;
0983
0984
0985 for (i=0; i<RTLISTID_MAX; i++) {
0986 priv->lists[i] = NULL;
0987 }
0988 }
0989
0990 int gr1553rt_config(void *rt, struct gr1553rt_cfg *cfg)
0991 {
0992 struct gr1553rt_priv *priv = rt;
0993 int retval = 0;
0994 if ( priv->started )
0995 return -1;
0996
0997
0998
0999 gr1553rt_sw_free(priv);
1000
1001
1002 if ( cfg->rtaddress > 30 )
1003 return -1;
1004 if ( (cfg->evlog_size & (cfg->evlog_size-1)) != 0)
1005 return -2;
1006 if ( ((unsigned int)priv->cfg.evlog_buffer & (cfg->evlog_size-1)) != 0 )
1007 return -2;
1008 #if (RTBD_MAX > 0)
1009 if ( cfg->bd_count > RTBD_MAX )
1010 return -1;
1011 #endif
1012
1013
1014 priv->cfg = *cfg;
1015
1016
1017
1018 if ( (retval=gr1553rt_sw_alloc(priv)) != 0 ) {
1019 return retval;
1020 }
1021
1022 gr1553rt_sw_init(priv);
1023
1024 return 0;
1025 }
1026
1027 int gr1553rt_start(void *rt)
1028 {
1029 struct gr1553rt_priv *priv = rt;
1030 SPIN_IRQFLAGS(irqflags);
1031
1032 if ( priv->started )
1033 return -1;
1034
1035
1036
1037 if ( !priv->satab_buffer || !priv->bd_buffer || !priv->evlog_buffer )
1038 return -2;
1039
1040 priv->evlog_cpu_next = priv->evlog_cpu_base;
1041
1042
1043
1044
1045 priv->regs->rt_tab = (unsigned int)priv->sas_hw;
1046
1047
1048 priv->regs->rt_mcctrl = priv->cfg.modecode;
1049
1050
1051 priv->regs->rt_ttag = priv->cfg.time_res << 16;
1052
1053
1054 priv->regs->rt_evsz = ~(priv->cfg.evlog_size - 1);
1055 priv->regs->rt_evlog = (unsigned int)priv->evlog_hw_base;
1056 priv->regs->rt_evirq = 0;
1057
1058
1059 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
1060 priv->regs->irq = GR1553B_IRQ_RTEV|GR1553B_IRQ_RTD|GR1553B_IRQ_RTTE;
1061 priv->regs->imask |= GR1553B_IRQEN_RTEVE | GR1553B_IRQEN_RTDE |
1062 GR1553B_IRQEN_RTTEE;
1063
1064
1065 priv->regs->rt_cfg = GR1553RT_KEY |
1066 (priv->cfg.rtaddress << GR1553B_RT_CFG_RTADDR_BIT) |
1067 GR1553B_RT_CFG_RTEN;
1068
1069
1070 priv->started = 1;
1071 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
1072
1073 return 0;
1074 }
1075
1076 void gr1553rt_stop(void *rt)
1077 {
1078 struct gr1553rt_priv *priv = rt;
1079 SPIN_IRQFLAGS(irqflags);
1080
1081 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
1082
1083
1084 gr1553rt_hw_stop(priv);
1085
1086
1087 priv->started = 0;
1088
1089 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
1090 }
1091
1092 void gr1553rt_sa_schedule(
1093 void *rt,
1094 int subadr,
1095 int tx,
1096 struct gr1553rt_list *list
1097 )
1098 {
1099 struct gr1553rt_priv *priv = rt;
1100 unsigned short bdid;
1101 struct gr1553rt_bd *bd;
1102
1103 if ( !list || (list->listid == -1) )
1104 return;
1105
1106
1107 bdid = list->bds[0];
1108 if ( bdid == 0xffff )
1109 return;
1110 bd = &priv->bds_hw[bdid];
1111
1112 list->subadr = subadr;
1113
1114
1115 if ( tx ) {
1116 list->subadr |= 0x100;
1117 priv->subadrs[subadr].txlistid = list->listid;
1118 priv->sas_cpu[subadr].txptr = (unsigned int)bd;
1119 } else {
1120 priv->subadrs[subadr].rxlistid = list->listid;
1121 priv->sas_cpu[subadr].rxptr = (unsigned int)bd;
1122 }
1123 }
1124
1125 void gr1553rt_sa_setopts(
1126 void *rt,
1127 int subadr,
1128 unsigned int mask,
1129 unsigned int options
1130 )
1131 {
1132 struct gr1553rt_priv *priv = rt;
1133 unsigned int ctrl;
1134
1135 if ( (subadr > 31) || (priv->sas_cpu == NULL) )
1136 return;
1137
1138 ctrl = priv->sas_cpu[subadr].ctrl;
1139 priv->sas_cpu[subadr].ctrl = (ctrl & ~mask) | options;
1140 }
1141
1142 void gr1553rt_set_vecword(void *rt, unsigned int mask, unsigned int words)
1143 {
1144 struct gr1553rt_priv *priv = rt;
1145 unsigned int vword;
1146
1147 if ( mask == 0 )
1148 return;
1149
1150 vword = priv->regs->rt_statw;
1151
1152 priv->regs->rt_statw = (vword & ~mask) | (words & mask);
1153 }
1154
1155 void gr1553rt_set_bussts(void *rt, unsigned int mask, unsigned int sts)
1156 {
1157 struct gr1553rt_priv *priv = rt;
1158 unsigned int stat;
1159
1160 stat = priv->regs->rt_stat2;
1161 priv->regs->rt_stat2 = (stat & ~mask) | (mask & sts);
1162 }
1163
1164 void gr1553rt_status(void *rt, struct gr1553rt_status *status)
1165 {
1166 struct gr1553rt_priv *priv = rt;
1167 struct gr1553b_regs *regs = priv->regs;
1168 unsigned int tmp;
1169 SPIN_IRQFLAGS(irqflags);
1170
1171 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
1172 status->status = regs->rt_stat;
1173 status->bus_status = regs->rt_stat2;
1174
1175 tmp = regs->rt_sync;
1176 status->synctime = tmp >> 16;
1177 status->syncword = tmp & 0xffff;
1178
1179 tmp = regs->rt_ttag;
1180 status->time_res = tmp >> 16;
1181 status->time = tmp & 0xffff;
1182
1183 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
1184 }
1185
1186 void gr1553rt_list_sa(struct gr1553rt_list *list, int *subadr, int *tx)
1187 {
1188 int sa, trt;
1189
1190 if ( list->subadr == -1 ) {
1191 sa = -1;
1192 trt = -1;
1193 } else {
1194 sa = list->subadr & 0xff;
1195 trt = (list->subadr & 0x100) >> 8;
1196 }
1197
1198 if ( subadr )
1199 *subadr = sa;
1200 if ( tx )
1201 *tx = trt;
1202 }
1203
1204 int gr1553rt_evlog_read(void *rt, unsigned int *dst, int max)
1205 {
1206 struct gr1553rt_priv *priv = rt;
1207 int cnt, top, bot, left;
1208 unsigned int *hwpos;
1209
1210
1211 hwpos = (unsigned int *)priv->regs->rt_evlog;
1212
1213
1214 hwpos = (unsigned int *)
1215 ((unsigned int)hwpos - (unsigned int)priv->evlog_hw_base +
1216 (unsigned int)priv->evlog_cpu_base);
1217
1218 if ( priv->evlog_cpu_next == hwpos )
1219 return 0;
1220
1221 if ( priv->evlog_cpu_next > hwpos ) {
1222 top = (unsigned int)priv->evlog_cpu_end -
1223 (unsigned int)priv->evlog_cpu_next;
1224 bot = (unsigned int)hwpos - (unsigned int)priv->evlog_cpu_base;
1225 } else {
1226 top = (unsigned int)hwpos - (unsigned int)priv->evlog_cpu_next;
1227 bot = 0;
1228 }
1229 top = top / 4;
1230 bot = bot / 4;
1231
1232 left = max;
1233 if ( top > 0 ) {
1234 if ( top > left ) {
1235 cnt = left;
1236 } else {
1237 cnt = top;
1238 }
1239 memcpy(dst, priv->evlog_cpu_next, cnt*4);
1240 dst += cnt;
1241 left -= cnt;
1242 }
1243
1244 if ( (bot > 0) && (left > 0) ) {
1245 if ( bot > left ) {
1246 cnt = left;
1247 } else {
1248 cnt = bot;
1249 }
1250 memcpy(dst, priv->evlog_cpu_base, cnt*4);
1251 left -= cnt;
1252 }
1253
1254 cnt = max - left;
1255 priv->evlog_cpu_next += cnt;
1256 if ( priv->evlog_cpu_next >= priv->evlog_cpu_end ) {
1257 priv->evlog_cpu_next = (unsigned int *)
1258 ((unsigned int)priv->evlog_cpu_base +
1259 ((unsigned int)priv->evlog_cpu_next -
1260 (unsigned int)priv->evlog_cpu_end ));
1261 }
1262
1263 return max - left;
1264 }