diff options
Diffstat (limited to 'c/src/lib/libbsp/sparc/shared/time/spwcuc.c')
-rw-r--r-- | c/src/lib/libbsp/sparc/shared/time/spwcuc.c | 370 |
1 files changed, 0 insertions, 370 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/time/spwcuc.c b/c/src/lib/libbsp/sparc/shared/time/spwcuc.c deleted file mode 100644 index 082ced0772..0000000000 --- a/c/src/lib/libbsp/sparc/shared/time/spwcuc.c +++ /dev/null @@ -1,370 +0,0 @@ -/* SPWCUC - SpaceWire - CCSDS unsegmented Code Transfer Protocol GRLIB core - * register driver interface. - * - * COPYRIGHT (c) 2009. - * Cobham Gaisler AB. - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include <drvmgr/drvmgr.h> -#include <drvmgr/ambapp_bus.h> -#include <stdlib.h> -#include <string.h> - -#include <bsp/spwcuc.h> - -/* Private structure of SPWCUC driver. */ -struct spwcuc_priv { - struct drvmgr_dev *dev; - struct spwcuc_regs *regs; - int open; - - spwcuc_isr_t user_isr; - void *user_isr_arg; - - struct spwcuc_stats stats; -}; - -void spwcuc_isr(void *data); - -struct amba_drv_info spwcuc_drv_info; - -/* Hardware Reset of SPWCUC */ -static int spwcuc_hw_reset(struct spwcuc_priv *priv) -{ - struct spwcuc_regs *r = priv->regs; - int i = 1000; - - r->control = 1; - - while ((r->control & 1) && i > 0) { - i--; - } - - spwcuc_clear_irqs(priv, -1); - - return i ? 0 : -1; -} - -int spwcuc_reset(void *spwcuc) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - return spwcuc_hw_reset(priv); -} - -void *spwcuc_open(int minor) -{ - struct spwcuc_priv *priv; - struct drvmgr_dev *dev; - - /* Get Device from Minor */ - if ( drvmgr_get_dev(&spwcuc_drv_info.general, minor, &dev) ) { - return NULL; - } - - priv = dev->priv; - if ( (priv == NULL) || priv->open ) - return NULL; - - /* Set initial state of software */ - priv->open = 1; - - /* Clear Statistics */ - spwcuc_clr_stats(priv); - priv->user_isr = NULL; - priv->user_isr_arg = NULL; - - return priv; -} - -void spwcuc_close(void *spwcuc) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - if ( priv->open == 0 ) - return; - - /* Reset Hardware */ - spwcuc_hw_reset(priv); - - priv->open = 0; -} - -void spwcuc_int_enable(void *spwcuc) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - /* Register and Enable Interrupt at Interrupt controller */ - drvmgr_interrupt_register(priv->dev, 0, "spwcuc", spwcuc_isr, priv); -} - -void spwcuc_int_disable(void *spwcuc) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - /* Enable Interrupt at Interrupt controller */ - drvmgr_interrupt_unregister(priv->dev, 0, spwcuc_isr, priv); -} - -void spwcuc_clr_stats(void *spwcuc) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - memset(&priv->stats, 0, sizeof(priv->stats)); -} - -void spwcuc_get_stats(void *spwcuc, struct spwcuc_stats *stats) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - memcpy(stats, &priv->stats, sizeof(priv->stats)); -} - -/* Configure the spwcuc core */ -void spwcuc_config(void *spwcuc, struct spwcuc_cfg *cfg) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - struct spwcuc_regs *r = priv->regs; - - r->config = (cfg->sel_out & 0x1f) << 28 | - (cfg->sel_in & 0x1f) << 24 | - (cfg->mapping & 0x1f) << 16 | - (cfg->tolerance & 0x1f) << 8 | - (cfg->tid & 0x7) << 4 | - (cfg->ctf & 1) << 1 | - (cfg->cp & 1); - - r->control = (cfg->txen & 1) << 1 | - (cfg->rxen & 1) << 2 | - (cfg->pktsyncen & 1) << 3 | - (cfg->pktiniten & 1) << 4 | - (cfg->pktrxen & 1) << 5; - - r->dla = (cfg->dla_mask & 0xff)<<8 | (cfg->dla & 0xff); - - r->pid = cfg->pid; - - r->offset = cfg->offset; -} - -/* Return elapsed coarse time */ -unsigned int spwcuc_get_et_coarse(void *spwcuc) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - return priv->regs->etct; -} - -/* Return elapsed fine time */ -unsigned int spwcuc_get_et_fine(void *spwcuc) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - return (priv->regs->etft & 0xffffff) >> 8; -} - -/* Return elapsed time (coarse and fine) */ -unsigned long long spwcuc_get_et(void *spwcuc) -{ - return (((unsigned long long)spwcuc_get_et_coarse(spwcuc)) << 24) | spwcuc_get_et_fine(spwcuc); -} - -/* Return next elapsed coarse time (for use when sending SpW time packet) */ -unsigned int spwcuc_get_next_et_coarse(void *spwcuc) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - return priv->regs->etct_next; -} - -/* Return next elapsed fine time (for use when sending SpW time packet) */ -unsigned int spwcuc_get_next_et_fine(void *spwcuc) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - return (priv->regs->etft_next & 0xffffff) >> 8; -} - -/* Return next elapsed time (for use when sending SpW time packet) */ -unsigned long long spwcuc_get_next_et(void *spwcuc) -{ - return (((unsigned long long)spwcuc_get_next_et_coarse(spwcuc)) << 24) | spwcuc_get_next_et_fine(spwcuc); -} - -/* Force/Set the elapsed time (coarse 32-bit and fine 24-bit) by writing the - * T-Field Time Packet Registers then the FORCE, NEW and INIT bits. - * The latter three are needed for the ET to be set with the new value. - */ -void spwcuc_force_et(void *spwcuc, unsigned long long time) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - struct spwcuc_regs *regs = priv->regs; - - regs->etft_next = (time & 0xffffff) << 8; - regs->etct_next = (time >> 24) & 0xffffffff; - regs->pkt_pf_crc = (1 << 29) | (1 << 30) | (1 << 31); -} - -/* Return received (from time packet) elapsed coarse time */ -unsigned int spwcuc_get_tp_et_coarse(void *spwcuc) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - return priv->regs->pkt_ct; -} - -/* Return received (from time packet) elapsed fine time */ -unsigned int spwcuc_get_tp_et_fine(void *spwcuc) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - return (priv->regs->pkt_ft & 0xffffff) >> 8; -} - -/* Return received (from time packet) elapsed time (coarse and fine) */ -unsigned long long spwcuc_get_tp_et(void *spwcuc) -{ - return (((unsigned long long)spwcuc_get_tp_et_coarse(spwcuc)) << 24) | spwcuc_get_tp_et_fine(spwcuc); -} - -/* Clear interrupts */ -void spwcuc_clear_irqs(void *spwcuc, int irqs) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - priv->regs->picr = irqs; -} - -/* Enable interrupts */ -void spwcuc_enable_irqs(void *spwcuc, int irqs) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - priv->regs->imr = irqs; -} - -struct spwcuc_regs *spwcuc_get_regs(void *spwcuc) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - return priv->regs; -} - -void spwcuc_int_register(void *spwcuc, spwcuc_isr_t func, void *data) -{ - struct spwcuc_priv *priv = (struct spwcuc_priv *)spwcuc; - - priv->user_isr = func; - priv->user_isr_arg = data; -} - -void spwcuc_isr(void *data) -{ - struct spwcuc_priv *priv = data; - struct spwcuc_stats *stats = &priv->stats; - unsigned int pimr = priv->regs->pimr; - - stats->nirqs++; - - if (pimr & PKT_INIT_IRQ) - stats->pkt_init++; - if (pimr & PKT_ERR_IRQ) - stats->pkt_err++; - if (pimr & PKT_RX_IRQ) - stats->pkt_rx++; - if (pimr & WRAP_ERR_IRQ) - stats->wraperr++; - if (pimr & WRAP_IRQ) - stats->wrap++; - if (pimr & SYNC_ERR_IRQ) - stats->syncerr++; - if (pimr & SYNC_IRQ) - stats->sync++; - if (pimr & TOL_ERR_IRQ) - stats->tolerr++; - if (pimr & TICK_RX_ERR_IRQ) - stats->tick_rx_error++; - if (pimr & TICK_RX_WRAP_IRQ) - stats->tick_rx_wrap++; - if (pimr & TICK_RX_IRQ) - stats->tick_rx++; - if (pimr & TICK_TX_WRAP_IRQ) - stats->tick_tx_wrap++; - if (pimr & TICK_TX_IRQ) - stats->tick_tx++; - - /* Let user Handle Interrupt */ - if ( priv->user_isr ) - priv->user_isr(pimr, priv->user_isr_arg); -} - -/*** INTERFACE TO DRIVER MANAGER ***/ - -static int spwcuc_init2(struct drvmgr_dev *dev) -{ - struct amba_dev_info *ambadev; - struct ambapp_core *pnpinfo; - struct spwcuc_priv *priv; - struct spwcuc_regs *regs; - - priv = (struct spwcuc_priv *)malloc(sizeof(*priv)); - if ( priv == NULL ) - return -1; - memset(priv, 0, sizeof(*priv)); - priv->dev = dev; - dev->priv = priv; - - /* Get device information from AMBA PnP information */ - ambadev = (struct amba_dev_info *)dev->businfo; - if ( ambadev == NULL ) { - return -1; - } - pnpinfo = &ambadev->info; - regs = (struct spwcuc_regs *)pnpinfo->apb_slv->start; - - priv->regs = regs; - - spwcuc_hw_reset(priv); - - return 0; -} - -struct drvmgr_drv_ops spwcuc_ops = -{ - {NULL, spwcuc_init2, NULL, NULL}, - NULL, - NULL -}; - -struct amba_dev_id spwcuc_ids[] = -{ - {VENDOR_GAISLER, GAISLER_SPWCUC}, - {0, 0} /* Mark end of table */ -}; - -struct amba_drv_info spwcuc_drv_info = -{ - { - DRVMGR_OBJ_DRV, /* Driver */ - NULL, /* Next driver */ - NULL, /* Device list */ - DRIVER_AMBAPP_GAISLER_SPWCUC_ID,/* Driver ID */ - "SPWCUC_DRV", /* Driver Name */ - DRVMGR_BUS_TYPE_AMBAPP, /* Bus Type */ - &spwcuc_ops, - NULL, /* Funcs */ - 0, /* No devices yet */ - 0, - }, - &spwcuc_ids[0] -}; - -/* Register the SPWCUC Driver */ -void spwcuc_register(void) -{ - drvmgr_drv_register(&spwcuc_drv_info.general); -} |