Changeset 72ec13e in rtems


Ignore:
Timestamp:
Jan 22, 2017, 2:35:27 PM (4 years ago)
Author:
Daniel Hellstrom <daniel@…>
Branches:
5, master
Children:
8acfa94
Parents:
29c2304
git-author:
Daniel Hellstrom <daniel@…> (01/22/17 14:35:27)
git-committer:
Daniel Hellstrom <daniel@…> (03/06/17 06:54:55)
Message:

leon, grspw_pkt: functions to support custom work-task

Added new function:

  • grspw_dma_ctrlsts() - Read value of DMA CTRL/STS reg.
  • grspw_dma_enable_int() - re-enable interrupt, used when

implementing a custom work-task.

Location:
c/src/lib/libbsp/sparc/shared
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/shared/include/grspw_pkt.h

    r29c2304 r72ec13e  
    536536extern void grspw_dma_stop(void *c);
    537537
     538/* Enable interrupt manually */
     539extern unsigned int grspw_dma_enable_int(void *c, int rxtx, int force);
     540
     541/* Return Current DMA Control & Status Register */
     542extern unsigned int grspw_dma_ctrlsts(void *c);
     543
    538544/* Schedule List of packets for transmission at some point in
    539545 * future.
  • c/src/lib/libbsp/sparc/shared/spw/grspw_pkt.c

    r29c2304 r72ec13e  
    731731}
    732732
     733/* Return Current DMA CTRL/Status Register */
     734unsigned int grspw_dma_ctrlsts(void *c)
     735{
     736        struct grspw_dma_priv *dma = c;
     737
     738        return REG_READ(&dma->regs->ctrl);
     739}
     740
    733741/* Return Current Status Register */
    734742unsigned int grspw_link_status(void *d)
     
    18211829        dma->open = 0;
    18221830        return 0;
     1831}
     1832
     1833unsigned int grspw_dma_enable_int(void *c, int rxtx, int force)
     1834{
     1835        struct grspw_dma_priv *dma = c;
     1836        int rc = 0;
     1837        unsigned int ctrl, ctrl_old;
     1838        IRQFLAGS_TYPE irqflags;
     1839
     1840        SPIN_LOCK_IRQ(&dma->core->devlock, irqflags);
     1841        if (dma->started == 0) {
     1842                rc = 1; /* DMA stopped */
     1843                goto out;
     1844        }
     1845        ctrl = REG_READ(&dma->regs->ctrl);
     1846        ctrl_old = ctrl;
     1847
     1848        /* Read/Write DMA error ? */
     1849        if (ctrl & GRSPW_DMA_STATUS_ERROR) {
     1850                rc = 2; /* DMA error */
     1851                goto out;
     1852        }
     1853
     1854        /* DMA has finished a TX/RX packet and user wants work-task to
     1855         * take care of DMA table processing.
     1856         */
     1857        ctrl &= ~GRSPW_DMACTRL_AT;
     1858
     1859        if ((rxtx & 1) == 0)
     1860                ctrl &= ~GRSPW_DMACTRL_PR;
     1861        else if (force || ((dma->cfg.rx_irq_en_cnt != 0) ||
     1862                 (dma->cfg.flags & DMAFLAG2_RXIE)))
     1863                ctrl |= GRSPW_DMACTRL_RI;
     1864
     1865        if ((rxtx & 2) == 0)
     1866                ctrl &= ~GRSPW_DMACTRL_PS;
     1867        else if (force || ((dma->cfg.tx_irq_en_cnt != 0) ||
     1868                 (dma->cfg.flags & DMAFLAG2_TXIE)))
     1869                ctrl |= GRSPW_DMACTRL_TI;
     1870
     1871        REG_WRITE(&dma->regs->ctrl, ctrl);
     1872        /* Re-enabled interrupts previously enabled */
     1873        rc = ctrl_old & (GRSPW_DMACTRL_PR | GRSPW_DMACTRL_PS);
     1874out:
     1875        SPIN_UNLOCK_IRQ(&dma->core->devlock, irqflags);
     1876        return rc;
    18231877}
    18241878
     
    25432597static void grspw_work_dma_func(struct grspw_dma_priv *dma, unsigned int msg)
    25442598{
    2545         int tx_cond_true, rx_cond_true;
    2546         unsigned int ctrl;
    2547         IRQFLAGS_TYPE irqflags;
     2599        int tx_cond_true, rx_cond_true, rxtx;
    25482600
    25492601        /* If DMA channel is closed we should not access the semaphore */
     
    25512603                return;
    25522604
    2553         rx_cond_true = 0;
    2554         tx_cond_true = 0;
    25552605        dma->stats.irq_cnt++;
    25562606
    25572607        /* Look at cause we were woken up and clear source */
    2558         SPIN_LOCK_IRQ(&priv->devlock, irqflags);
    2559         if (dma->started == 0) {
    2560                 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     2608        rxtx = 0;
     2609        if (msg & WORK_DMA_RX_MASK)
     2610                rxtx |= 1;
     2611        if (msg & WORK_DMA_TX_MASK)
     2612                rxtx |= 2;
     2613        switch (grspw_dma_enable_int(dma, rxtx, 0)) {
     2614        case 1:
     2615                /* DMA stopped */
    25612616                return;
    2562         }
    2563         ctrl = REG_READ(&dma->regs->ctrl);
    2564 
    2565         /* Read/Write DMA error ? */
    2566         if (ctrl & GRSPW_DMA_STATUS_ERROR) {
     2617        case 2:
    25672618                /* DMA error -> Stop DMA channel (both RX and TX) */
    2568                 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    25692619                if (msg & WORK_DMA_ER_MASK) {
    25702620                        /* DMA error and user wants work-task to handle error */
     
    25722622                        grspw_work_event(WORKTASK_EV_DMA_STOP, msg);
    25732623                }
    2574         } else if (((msg & WORK_DMA_RX_MASK) && (ctrl & GRSPW_DMACTRL_PR)) ||
    2575                    ((msg & WORK_DMA_TX_MASK) && (ctrl & GRSPW_DMACTRL_PS))) {
    2576                 /* DMA has finished a TX/RX packet and user wants work-task to
    2577                  * take care of DMA table processing.
    2578                  */
    2579                 ctrl &= ~GRSPW_DMACTRL_AT;
    2580 
    2581                 if ((msg & WORK_DMA_RX_MASK) == 0)
    2582                         ctrl &= ~GRSPW_DMACTRL_PR;
    2583                 else if (dma->cfg.rx_irq_en_cnt != 0 ||
    2584                          (dma->cfg.flags & DMAFLAG2_RXIE))
    2585                         ctrl |= GRSPW_DMACTRL_RI;
    2586                 if ((msg & WORK_DMA_TX_MASK) == 0)
    2587                         ctrl &= ~GRSPW_DMACTRL_PS;
    2588                 else if ((dma->cfg.tx_irq_en_cnt != 0 ||
    2589                          (dma->cfg.flags & DMAFLAG2_TXIE)))
    2590                         ctrl |= GRSPW_DMACTRL_TI;
    2591 
    2592                 REG_WRITE(&dma->regs->ctrl, ctrl);
    2593                 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
    2594                 if ((msg & WORK_DMA_RX_MASK) && (ctrl & GRSPW_DMACTRL_PR)) {
    2595                         /* Do RX Work */
    2596 
    2597                         /* Take DMA channel RX lock */
    2598                         if (rtems_semaphore_obtain(dma->sem_rxdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
    2599                             != RTEMS_SUCCESSFUL)
    2600                                 return;
    2601 
    2602                         dma->stats.rx_work_cnt++;
    2603                         grspw_rx_process_scheduled(dma);
    2604                         if (dma->started) {
    2605                                 dma->stats.rx_work_enabled +=
    2606                                         grspw_rx_schedule_ready(dma);
    2607                                 /* Check to see if condition for waking blocked
    2608                                  * USER task is fullfilled.
    2609                                  */
    2610                                 if (dma->rx_wait.waiting)
    2611                                         rx_cond_true = grspw_rx_wait_eval(dma);
    2612                         }
    2613                         rtems_semaphore_release(dma->sem_rxdma);
     2624                return;
     2625        default:
     2626                break;
     2627        }
     2628
     2629        rx_cond_true = 0;
     2630        tx_cond_true = 0;
     2631
     2632        if (msg & WORK_DMA_RX_MASK) {
     2633                /* Do RX Work */
     2634
     2635                /* Take DMA channel RX lock */
     2636                if (rtems_semaphore_obtain(dma->sem_rxdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
     2637                    != RTEMS_SUCCESSFUL)
     2638                        return;
     2639
     2640                dma->stats.rx_work_cnt++;
     2641                grspw_rx_process_scheduled(dma);
     2642                if (dma->started) {
     2643                        dma->stats.rx_work_enabled +=
     2644                                grspw_rx_schedule_ready(dma);
     2645                        /* Check to see if condition for waking blocked
     2646                         * USER task is fullfilled.
     2647                         */
     2648                        if (dma->rx_wait.waiting)
     2649                                rx_cond_true = grspw_rx_wait_eval(dma);
    26142650                }
    2615                 if ((msg & WORK_DMA_TX_MASK) && (ctrl & GRSPW_DMACTRL_PS)) {
    2616                         /* Do TX Work */
    2617 
    2618                         /* Take DMA channel TX lock */
    2619                         if (rtems_semaphore_obtain(dma->sem_txdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
    2620                             != RTEMS_SUCCESSFUL)
    2621                                 return;
    2622 
    2623                         dma->stats.tx_work_cnt++;
    2624                         grspw_tx_process_scheduled(dma);
    2625                         if (dma->started) {
    2626                                 dma->stats.tx_work_enabled +=
    2627                                         grspw_tx_schedule_send(dma);
    2628                                 /* Check to see if condition for waking blocked
    2629                                  * USER task is fullfilled.
    2630                                  */
    2631                                 if (dma->tx_wait.waiting)
    2632                                         tx_cond_true = grspw_tx_wait_eval(dma);
    2633                         }
    2634                         rtems_semaphore_release(dma->sem_txdma);
     2651                rtems_semaphore_release(dma->sem_rxdma);
     2652        }
     2653
     2654        if (msg & WORK_DMA_TX_MASK) {
     2655                /* Do TX Work */
     2656
     2657                /* Take DMA channel TX lock */
     2658                if (rtems_semaphore_obtain(dma->sem_txdma, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
     2659                    != RTEMS_SUCCESSFUL)
     2660                        return;
     2661
     2662                dma->stats.tx_work_cnt++;
     2663                grspw_tx_process_scheduled(dma);
     2664                if (dma->started) {
     2665                        dma->stats.tx_work_enabled +=
     2666                                grspw_tx_schedule_send(dma);
     2667                        /* Check to see if condition for waking blocked
     2668                         * USER task is fullfilled.
     2669                         */
     2670                        if (dma->tx_wait.waiting)
     2671                                tx_cond_true = grspw_tx_wait_eval(dma);
    26352672                }
    2636         } else
    2637                 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
     2673                rtems_semaphore_release(dma->sem_txdma);
     2674        }
    26382675
    26392676        if (rx_cond_true)
Note: See TracChangeset for help on using the changeset viewer.