summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-20 12:08:42 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-20 13:52:19 +0200
commite0dd8a5ad830798bc8082b03b8c42c32fb9660e0 (patch)
treed147bfc4d670fcdfbd2e2d2e75eb209f92e07df1 /c/src/lib/libbsp/sparc
parentbsps: Move startup files to bsps (diff)
downloadrtems-e0dd8a5ad830798bc8082b03b8c42c32fb9660e0.tar.bz2
bsps: Move benchmark timer to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'c/src/lib/libbsp/sparc')
-rw-r--r--c/src/lib/libbsp/sparc/erc32/Makefile.am2
-rw-r--r--c/src/lib/libbsp/sparc/erc32/timer/timer.c81
-rw-r--r--c/src/lib/libbsp/sparc/leon2/Makefile.am6
-rw-r--r--c/src/lib/libbsp/sparc/leon2/timer/timer.c83
-rw-r--r--c/src/lib/libbsp/sparc/leon3/Makefile.am10
-rw-r--r--c/src/lib/libbsp/sparc/leon3/timer/timer.c85
-rw-r--r--c/src/lib/libbsp/sparc/leon3/timer/watchdog.c90
-rw-r--r--c/src/lib/libbsp/sparc/shared/timer/gptimer.c544
-rw-r--r--c/src/lib/libbsp/sparc/shared/timer/tlib.c77
-rw-r--r--c/src/lib/libbsp/sparc/shared/timer/tlib_ckinit.c453
10 files changed, 9 insertions, 1422 deletions
diff --git a/c/src/lib/libbsp/sparc/erc32/Makefile.am b/c/src/lib/libbsp/sparc/erc32/Makefile.am
index 3171e0b697..7668a98610 100644
--- a/c/src/lib/libbsp/sparc/erc32/Makefile.am
+++ b/c/src/lib/libbsp/sparc/erc32/Makefile.am
@@ -50,7 +50,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/console/debugputs.c
# clock
librtemsbsp_a_SOURCES +=../../../../../../bsps/sparc/erc32/clock/ckinit.c
# timer
-librtemsbsp_a_SOURCES += timer/timer.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/erc32/btimer/btimer.c
# IRQ
librtemsbsp_a_SOURCES += ../shared/irq/irq-shared.c
diff --git a/c/src/lib/libbsp/sparc/erc32/timer/timer.c b/c/src/lib/libbsp/sparc/erc32/timer/timer.c
deleted file mode 100644
index 05728f8acc..0000000000
--- a/c/src/lib/libbsp/sparc/erc32/timer/timer.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* timer.c
- *
- * This file implements a benchmark timer using the General Purpose Timer on
- * the MEC.
- *
- * COPYRIGHT (c) 1989-1999.
- * On-Line Applications Research Corporation (OAR).
- *
- * 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.
- *
- * Ported to ERC32 implementation of the SPARC by On-Line Applications
- * Research Corporation (OAR) under contract to the European Space
- * Agency (ESA).
- *
- * ERC32 modifications of respective RTEMS file: COPYRIGHT (c) 1995.
- * European Space Agency.
- */
-
-#include <bsp.h>
-#include <rtems/btimer.h>
-
-bool benchmark_timer_find_average_overhead;
-
-bool benchmark_timer_is_initialized = false;
-
-void benchmark_timer_initialize(void)
-{
- /*
- * Timer runs long and accurate enough not to require an interrupt.
- */
-
- if ( benchmark_timer_is_initialized == false ) {
-
- /* approximately 1 us per countdown */
- ERC32_MEC.General_Purpose_Timer_Scalar = CLOCK_SPEED - 1;
- ERC32_MEC.General_Purpose_Timer_Counter = 0xffffffff;
-
- } else {
- benchmark_timer_is_initialized = true;
- }
-
- ERC32_MEC_Set_General_Purpose_Timer_Control(
- ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING |
- ERC32_MEC_TIMER_COUNTER_LOAD_COUNTER
- );
-
- ERC32_MEC_Set_General_Purpose_Timer_Control(
- ERC32_MEC_TIMER_COUNTER_ENABLE_COUNTING
- );
-
-}
-
-#define AVG_OVERHEAD 12 /* It typically takes 3.0 microseconds */
- /* to start/stop the timer. */
-#define LEAST_VALID 13 /* Don't trust a value lower than this */
-
-benchmark_timer_t benchmark_timer_read(void)
-{
- uint32_t total;
-
- total = ERC32_MEC.General_Purpose_Timer_Counter;
-
- total = 0xffffffff - total;
-
- if ( benchmark_timer_find_average_overhead == true )
- return total; /* in one microsecond units */
-
- if ( total < LEAST_VALID )
- return 0; /* below timer resolution */
-
- return total - AVG_OVERHEAD;
-}
-
-void benchmark_timer_disable_subtracting_average_overhead(
- bool find_flag
-)
-{
- benchmark_timer_find_average_overhead = find_flag;
-}
diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am
index 34cd6fcd12..7e5d8b6363 100644
--- a/c/src/lib/libbsp/sparc/leon2/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am
@@ -66,8 +66,8 @@ librtemsbsp_a_SOURCES += ../shared/amba/ambapp_show.c
librtemsbsp_a_SOURCES += ../shared/amba/ahbstat.c
# Clock Driver and Timer Library
-librtemsbsp_a_SOURCES += ../shared/timer/gptimer.c
-librtemsbsp_a_SOURCES += ../shared/timer/tlib.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/btimer/gptimer.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/btimer/tlib.c
# PCI
librtemsbsp_a_SOURCES += ../shared/pci/grpci2.c
@@ -137,7 +137,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/start/cache.c
# griommu
librtemsbsp_a_SOURCES += ../shared/iommu/griommu.c
# timer
-librtemsbsp_a_SOURCES += timer/timer.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon2/btimer/btimer.c
# TM/TC
librtemsbsp_a_SOURCES += ../shared/tmtc/grtc.c
diff --git a/c/src/lib/libbsp/sparc/leon2/timer/timer.c b/c/src/lib/libbsp/sparc/leon2/timer/timer.c
deleted file mode 100644
index de115c965a..0000000000
--- a/c/src/lib/libbsp/sparc/leon2/timer/timer.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * @file
- * @ingroup sparc_leon2
- * @brief Implement a benchmark timer using timer 2
- */
-
-/* timer.c
- *
- * This file implements a benchmark timer using timer 2.
- *
- * COPYRIGHT (c) 1989-1998.
- * On-Line Applications Research Corporation (OAR).
- *
- * 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.
- *
- * Ported to LEON implementation of the SPARC by On-Line Applications
- * Research Corporation (OAR) under contract to the European Space
- * Agency (ESA).
- *
- * LEON modifications of respective RTEMS file: COPYRIGHT (c) 1995.
- * European Space Agency.
- */
-
-
-#include <bsp.h>
-#include <rtems/btimer.h>
-
-bool benchmark_timer_find_average_overhead;
-
-bool benchmark_timer_is_initialized = false;
-
-void benchmark_timer_initialize(void)
-{
- /*
- * Timer runs long and accurate enough not to require an interrupt.
- */
-
- if ( benchmark_timer_is_initialized == false ) {
-
- /* approximately 1 us per countdown */
- LEON_REG.Timer_Counter_2 = 0xffffff;
- LEON_REG.Timer_Reload_2 = 0xffffff;
-
- } else {
- benchmark_timer_is_initialized = true;
- }
-
- LEON_REG.Timer_Control_2 = (
- LEON_REG_TIMER_COUNTER_ENABLE_COUNTING |
- LEON_REG_TIMER_COUNTER_LOAD_COUNTER
- );
-
-}
-
-#define AVG_OVERHEAD 3 /* It typically takes 3.0 microseconds */
- /* to start/stop the timer. */
-#define LEAST_VALID 2 /* Don't trust a value lower than this */
-
-benchmark_timer_t benchmark_timer_read(void)
-{
- uint32_t total;
-
- total = LEON_REG.Timer_Counter_2;
-
- total = 0xffffff - total;
-
- if ( benchmark_timer_find_average_overhead == true )
- return total; /* in one microsecond units */
-
- if ( total < LEAST_VALID )
- return 0; /* below timer resolution */
-
- return total - AVG_OVERHEAD;
-}
-
-void benchmark_timer_disable_subtracting_average_overhead(
- bool find_flag
-)
-{
- benchmark_timer_find_average_overhead = find_flag;
-}
diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am
index df75c03552..71a020cd17 100644
--- a/c/src/lib/libbsp/sparc/leon3/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am
@@ -60,9 +60,9 @@ librtemsbsp_a_SOURCES += ../shared/amba/ambapp_show.c
librtemsbsp_a_SOURCES += ../shared/amba/ahbstat.c
# Clock Driver and Timer Library
-librtemsbsp_a_SOURCES += ../shared/timer/gptimer.c
-librtemsbsp_a_SOURCES += ../shared/timer/tlib.c
-librtemsbsp_a_SOURCES += ../shared/timer/tlib_ckinit.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/btimer/gptimer.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/btimer/tlib.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/shared/btimer/tlib_ckinit.c
# non-Driver Manager Clock Implementation
librtemsbsp_a_SOURCES +=../../../../../../bsps/sparc/leon3/clock/ckinit.c
@@ -151,8 +151,8 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/start/cache.c
# griommu
librtemsbsp_a_SOURCES += ../shared/iommu/griommu.c
# timer
-librtemsbsp_a_SOURCES += timer/timer.c
-librtemsbsp_a_SOURCES += timer/watchdog.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/btimer/btimer.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/btimer/watchdog.c
# GR712
librtemsbsp_a_SOURCES += ../shared/ascs/grascs.c
diff --git a/c/src/lib/libbsp/sparc/leon3/timer/timer.c b/c/src/lib/libbsp/sparc/leon3/timer/timer.c
deleted file mode 100644
index 40bdeb87bb..0000000000
--- a/c/src/lib/libbsp/sparc/leon3/timer/timer.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* timer.c
- *
- * This file implements a benchmark timer using timer 2.
- *
- * COPYRIGHT (c) 1989-1998.
- * On-Line Applications Research Corporation (OAR).
- *
- * 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.
- *
- * Ported to LEON implementation of the SPARC by On-Line Applications
- * Research Corporation (OAR) under contract to the European Space
- * Agency (ESA).
- *
- * LEON modifications of respective RTEMS file: COPYRIGHT (c) 1995.
- * European Space Agency.
- */
-
-
-#include <bsp.h>
-#include <rtems/btimer.h>
-
-#if defined(RTEMS_MULTIPROCESSING)
- #define LEON3_TIMER_INDEX \
- ((rtems_configuration_get_user_multiprocessing_table()) ? \
- (rtems_configuration_get_user_multiprocessing_table()->node) - 1 : 1)
-#else
- #define LEON3_TIMER_INDEX 0
-#endif
-
-bool benchmark_timer_find_average_overhead;
-
-bool benchmark_timer_is_initialized = false;
-
-extern volatile struct gptimer_regs *LEON3_Timer_Regs;
-
-void benchmark_timer_initialize(void)
-{
- /*
- * Timer runs long and accurate enough not to require an interrupt.
- */
- if (LEON3_Timer_Regs) {
- if ( benchmark_timer_is_initialized == false ) {
- /* approximately 1 us per countdown */
- LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].reload = 0xffffff;
- LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].value = 0xffffff;
- } else {
- benchmark_timer_is_initialized = true;
- }
- LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].ctrl =
- GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_LD;
- }
-}
-
-#define AVG_OVERHEAD 3 /* It typically takes 3.0 microseconds */
- /* to start/stop the timer. */
-#define LEAST_VALID 2 /* Don't trust a value lower than this */
-
-benchmark_timer_t benchmark_timer_read(void)
-{
- uint32_t total;
-
- if (LEON3_Timer_Regs) {
- total = LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].value;
-
- total = 0xffffff - total;
-
- if ( benchmark_timer_find_average_overhead == true )
- return total; /* in one microsecond units */
-
- if ( total < LEAST_VALID )
- return 0; /* below timer resolution */
-
- return total - AVG_OVERHEAD;
- }
- return 0;
-}
-
-void benchmark_timer_disable_subtracting_average_overhead(
- bool find_flag
-)
-{
- benchmark_timer_find_average_overhead = find_flag;
-}
diff --git a/c/src/lib/libbsp/sparc/leon3/timer/watchdog.c b/c/src/lib/libbsp/sparc/leon3/timer/watchdog.c
deleted file mode 100644
index 5ce8e32354..0000000000
--- a/c/src/lib/libbsp/sparc/leon3/timer/watchdog.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/* GPTIMER Watchdog timer routines. On some systems the first GPTIMER
- * core's last Timer instance underflow signal is connected to system
- * reset.
- *
- * COPYRIGHT (c) 2012.
- * 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 <bsp.h>
-#include <bsp/watchdog.h>
-#include <grlib.h>
-
-extern volatile struct gptimer_regs *LEON3_Timer_Regs;
-
-struct gptimer_watchdog_priv {
- struct gptimer_regs *regs;
- struct gptimer_timer_regs *timer;
- int timerno;
-};
-
-struct gptimer_watchdog_priv bsp_watchdogs[1];
-int bsp_watchdog_count = 0;
-
-int bsp_watchdog_init(void)
-{
- int timercnt;
-
- if (!LEON3_Timer_Regs)
- return 0;
-
- /* Get Watchdogs in system, this is implemented for one GPTIMER core
- * only.
- *
- * First watchdog is a special case, we can get the first timer core by
- * looking at LEON3_Timer_Regs, the watchdog within a timer core is
- * always the last timer. Unfortunately we can not know it the watchdog
- * functionality is available or not, we assume that it is if we
- * reached this function.
- */
- bsp_watchdogs[0].regs = (struct gptimer_regs *)LEON3_Timer_Regs;
-
- /* Find Timer that has watchdog functionality */
- timercnt = bsp_watchdogs[0].regs->cfg & 0x7;
- if (timercnt < 2) /* First timer system clock timer */
- return 0;
-
- bsp_watchdogs[0].timerno = timercnt - 1;
- bsp_watchdogs[0].timer = &bsp_watchdogs[0].regs->timer[bsp_watchdogs[0].timerno];
-
- bsp_watchdog_count = 1;
- return bsp_watchdog_count;
-}
-
-void bsp_watchdog_reload(int watchdog, unsigned int reload_value)
-{
- if (bsp_watchdog_count == 0)
- bsp_watchdog_init();
-
- if (bsp_watchdog_count <= watchdog)
- return;
-
- /* Kick watchdog, and clear interrupt pending bit */
- bsp_watchdogs[watchdog].timer->reload = reload_value;
- bsp_watchdogs[watchdog].timer->ctrl =
- (GPTIMER_TIMER_CTRL_LD | GPTIMER_TIMER_CTRL_EN) |
- (bsp_watchdogs[watchdog].timer->ctrl & ~(1<<4));
-}
-
-void bsp_watchdog_stop(int watchdog)
-{
- if (bsp_watchdog_count == 0)
- bsp_watchdog_init();
-
- if (bsp_watchdog_count <= watchdog)
- return;
-
- /* Stop watchdog timer */
- bsp_watchdogs[watchdog].timer->ctrl = 0;
-}
-
-/* Use watchdog timer to reset system */
-void bsp_watchdog_system_reset(void)
-{
- sparc_disable_interrupts();
- bsp_watchdog_reload(0, 1);
-}
diff --git a/c/src/lib/libbsp/sparc/shared/timer/gptimer.c b/c/src/lib/libbsp/sparc/shared/timer/gptimer.c
deleted file mode 100644
index 08e498178e..0000000000
--- a/c/src/lib/libbsp/sparc/shared/timer/gptimer.c
+++ /dev/null
@@ -1,544 +0,0 @@
-/* This file contains the driver for the GRLIB GPTIMER timers port. The driver
- * is implemented by using the tlib.c simple timer layer and the Driver
- * Manager.
- *
- * The Driver can be configured using driver resources:
- *
- * - timerStart Timer Index if first Timer, this parameters is typically used
- * in AMP systems for resource allocation. The Timers before
- * timerStart will not be accessed.
- * - timerCnt Number of timers that the driver will use, this parameters is
- * typically used in AMP systems for resource allocation between
- * OS instances.
- * - prescaler Base prescaler, normally set by bootloader but can be
- * overridden. The default scaler reload value set by bootloader
- * is so that Timers operate in 1MHz. Setting the prescaler to a
- * lower value increase the accuracy of the timers but shortens
- * the time until underflow happens.
- * - clockTimer Used to select a particular timer to be the system clock
- * timer. This is useful when multiple GPTIMERs cores are
- * available, or in AMP systems. By default the TLIB selects the
- * first timer registered as system clock timer.
- *
- * The BSP define APBUART_INFO_AVAIL in order to add the info routine
- * used for debugging.
- *
- * COPYRIGHT (c) 2010.
- * 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 <rtems.h>
-#include <bsp.h>
-#include <stdlib.h>
-#include <string.h>
-#include <drvmgr/drvmgr.h>
-#include <drvmgr/ambapp_bus.h>
-#include <grlib.h>
-#include <bsp/gptimer.h>
-#include <bsp/tlib.h>
-
-#if defined(LEON3)
-#include <leon.h>
-#endif
-
-#ifdef GPTIMER_INFO_AVAIL
-#include <stdio.h>
-#endif
-
-#ifdef RTEMS_SMP
-#include <rtems/score/processormask.h>
-#include <rtems/score/smpimpl.h>
-#endif
-
-/* GPTIMER Core Configuration Register (READ-ONLY) */
-#define GPTIMER_CFG_TIMERS_BIT 0
-#define GPTIMER_CFG_IRQ_BIT 3
-#define GPTIMER_CFG_SI_BIT 8
-#define GPTIMER_CFG_DF_BIT 9
-
-#define GPTIMER_CFG_TIMERS (0x7<<GPTIMER_CFG_TIMERS_BIT)
-#define GPTIMER_CFG_IRQ (0x1f<<GPTIMER_CFG_IRQ_BIT)
-#define GPTIMER_CFG_SI (1<<GPTIMER_CFG_SI_BIT)
-#define GPTIMER_CFG_DF (1<<GPTIMER_CFG_DF_BIT)
-
-/* GPTIMER Timer Control Register */
-#define GPTIMER_CTRL_EN_BIT 0
-#define GPTIMER_CTRL_RS_BIT 1
-#define GPTIMER_CTRL_LD_BIT 2
-#define GPTIMER_CTRL_IE_BIT 3
-#define GPTIMER_CTRL_IP_BIT 4
-#define GPTIMER_CTRL_CH_BIT 5
-#define GPTIMER_CTRL_DH_BIT 6
-
-#define GPTIMER_CTRL_EN (1<<GPTIMER_CTRL_EN_BIT)
-#define GPTIMER_CTRL_RS (1<<GPTIMER_CTRL_RS_BIT)
-#define GPTIMER_CTRL_LD (1<<GPTIMER_CTRL_LD_BIT)
-#define GPTIMER_CTRL_IE (1<<GPTIMER_CTRL_IE_BIT)
-#define GPTIMER_CTRL_IP (1<<GPTIMER_CTRL_IP_BIT)
-#define GPTIMER_CTRL_CH (1<<GPTIMER_CTRL_CH_BIT)
-#define GPTIMER_CTRL_DH (1<<GPTIMER_CTRL_DH_BIT)
-
-#define DBG(x...)
-
-/* GPTIMER timer private */
-struct gptimer_timer {
- struct tlib_dev tdev; /* Must be first in struct */
- struct gptimer_timer_regs *tregs;
- char index; /* Timer Index in this driver */
- char tindex; /* Timer Index In Hardware */
- unsigned char irq_ack_mask;
-};
-
-/* GPTIMER Core private */
-struct gptimer_priv {
- struct drvmgr_dev *dev;
- struct gptimer_regs *regs;
- unsigned int base_clk;
- unsigned int base_freq;
- unsigned int widthmask;
- char separate_interrupt;
- char isr_installed;
-
- /* Structure per Timer unit, the core supports up to 8 timers */
- int timer_cnt;
- struct gptimer_timer timers[0];
-};
-
-void gptimer_isr(void *data);
-
-#if 0
-void gptimer_tlib_irq_register(struct tlib_drv *tdrv, tlib_isr_t func, void *data)
-{
- struct gptimer_priv *priv = (struct gptimer_priv *)tdrv;
-
- if ( SHARED ...)
-
-
- drvmgr_interrupt_register();
-}
-#endif
-
-/******************* Driver manager interface ***********************/
-
-/* Driver prototypes */
-static struct tlib_drv gptimer_tlib_drv;
-int gptimer_device_init(struct gptimer_priv *priv);
-
-int gptimer_init1(struct drvmgr_dev *dev);
-#ifdef GPTIMER_INFO_AVAIL
-static int gptimer_info(
- struct drvmgr_dev *dev,
- void (*print_line)(void *p, char *str),
- void *p, int, char *argv[]);
-#define GTIMER_INFO_FUNC gptimer_info
-#else
-#define GTIMER_INFO_FUNC NULL
-#endif
-
-struct drvmgr_drv_ops gptimer_ops =
-{
- .init = {gptimer_init1, NULL, NULL, NULL},
- .remove = NULL,
- .info = GTIMER_INFO_FUNC,
-};
-
-struct amba_dev_id gptimer_ids[] =
-{
- {VENDOR_GAISLER, GAISLER_GPTIMER},
- {VENDOR_GAISLER, GAISLER_GRTIMER},
- {0, 0} /* Mark end of table */
-};
-
-struct amba_drv_info gptimer_drv_info =
-{
- {
- DRVMGR_OBJ_DRV, /* Driver */
- NULL, /* Next driver */
- NULL, /* Device list */
- DRIVER_AMBAPP_GAISLER_GPTIMER_ID,/* Driver ID */
- "GPTIMER_DRV", /* Driver Name */
- DRVMGR_BUS_TYPE_AMBAPP, /* Bus Type */
- &gptimer_ops,
- NULL, /* Funcs */
- 0, /* No devices yet */
- 0,
- },
- &gptimer_ids[0]
-};
-
-void gptimer_register_drv (void)
-{
- DBG("Registering GPTIMER driver\n");
- drvmgr_drv_register(&gptimer_drv_info.general);
-}
-
-int gptimer_init1(struct drvmgr_dev *dev)
-{
- struct gptimer_priv *priv;
- struct gptimer_regs *regs;
- struct amba_dev_info *ambadev;
- struct ambapp_core *pnpinfo;
- int timer_hw_cnt, timer_cnt, timer_start;
- int i, size;
- struct gptimer_timer *timer;
- union drvmgr_key_value *value;
- unsigned char irq_ack_mask;
-
- /* Get device information from AMBA PnP information */
- ambadev = (struct amba_dev_info *)dev->businfo;
- if ( ambadev == NULL ) {
- return -1;
- }
- pnpinfo = &ambadev->info;
- regs = (struct gptimer_regs *)pnpinfo->apb_slv->start;
-
- DBG("GPTIMER[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
-
- /* Get number of Timers */
- timer_hw_cnt = regs->cfg & GPTIMER_CFG_TIMERS;
-
- /* Let user spelect a range of timers to be used. In AMP systems
- * it is sometimes neccessary to leave timers for other CPU instances.
- *
- * The default operation in AMP is to shared the timers within the
- * first GPTIMER core as below. This can of course be overrided by
- * driver resources.
- */
- timer_cnt = timer_hw_cnt;
- timer_start = 0;
-#if defined(RTEMS_MULTIPROCESSING) && defined(LEON3)
- if ((dev->minor_drv == 0) && drvmgr_on_rootbus(dev)) {
- timer_cnt = 1;
- timer_start = LEON3_Cpu_Index;
- }
-#endif
- value = drvmgr_dev_key_get(dev, "timerStart", DRVMGR_KT_INT);
- if ( value) {
- timer_start = value->i;
- timer_cnt = timer_hw_cnt - timer_start;
- }
- value = drvmgr_dev_key_get(dev, "timerCnt", DRVMGR_KT_INT);
- if ( value && (value->i < timer_cnt) ) {
- timer_cnt = value->i;
- }
-
- /* Allocate Common Timer Description, size depends on how many timers
- * are present.
- */
- size = sizeof(struct gptimer_priv) +
- timer_cnt*sizeof(struct gptimer_timer);
- priv = dev->priv = (struct gptimer_priv *)malloc(size);
- if ( !priv )
- return DRVMGR_NOMEM;
- memset(priv, 0, size);
- priv->dev = dev;
- priv->regs = regs;
-
- /* The Base Frequency of the GPTIMER core is the same as the
- * frequency of the AMBA bus it is situated on.
- */
- drvmgr_freq_get(dev, DEV_APB_SLV, &priv->base_clk);
-
- /* This core will may provide important Timer functionality
- * to other drivers and the RTEMS kernel, the Clock driver
- * may for example use this device. So the Timer driver must be
- * initialized in the first iiitialization stage.
- */
-
- /*** Initialize Hardware ***/
-
- /* If user request to set prescaler, we will do that. However, note
- * that doing so for the Root-Bus GPTIMER may affect the RTEMS Clock
- * so that Clock frequency is wrong.
- */
- value = drvmgr_dev_key_get(priv->dev, "prescaler", DRVMGR_KT_INT);
- if ( value )
- regs->scaler_reload = value->i;
-
- /* Get Frequency that the timers are operating in (after prescaler) */
- priv->base_freq = priv->base_clk / (priv->regs->scaler_reload + 1);
-
- /* Stop Timer and probe Pending bit. In newer hardware the
- * timer has pending bit is cleared by writing a one to it,
- * whereas older versions it is cleared with a zero.
- */
- priv->regs->timer[timer_start].ctrl = GPTIMER_CTRL_IP;
- if ((priv->regs->timer[timer_start].ctrl & GPTIMER_CTRL_IP) != 0)
- irq_ack_mask = ~GPTIMER_CTRL_IP;
- else
- irq_ack_mask = ~0;
-
- /* Probe timer register width mask */
- priv->regs->timer[timer_start].value = 0xffffffff;
- priv->widthmask = priv->regs->timer[timer_start].value;
-
- priv->timer_cnt = timer_cnt;
- for (i=0; i<timer_cnt; i++) {
- timer = &priv->timers[i];
- timer->index = i;
- timer->tindex = i + timer_start;
- timer->tregs = &regs->timer[(int)timer->tindex];
- timer->tdev.drv = &gptimer_tlib_drv;
- timer->irq_ack_mask = irq_ack_mask;
-
- /* Register Timer at Timer Library */
- tlib_dev_reg(&timer->tdev);
- }
-
- /* Check Interrupt support implementation, two cases:
- * A. All Timers share one IRQ
- * B. Each Timer have an individual IRQ. The number is:
- * BASE_IRQ + timer_index
- */
- priv->separate_interrupt = (regs->cfg & GPTIMER_CFG_SI) != 0;
-
- return DRVMGR_OK;
-}
-
-#ifdef GPTIMER_INFO_AVAIL
-static int gptimer_info(
- struct drvmgr_dev *dev,
- void (*print_line)(void *p, char *str),
- void *p, int argc, char *argv[])
-{
- struct gptimer_priv *priv = dev->priv;
- struct gptimer_timer *timer;
- char buf[64];
- int i;
-
- if (priv == NULL || argc != 0)
- return -DRVMGR_EINVAL;
-
- sprintf(buf, "Timer Count: %d", priv->timer_cnt);
- print_line(p, buf);
- sprintf(buf, "REGS: 0x%08x", (unsigned int)priv->regs);
- print_line(p, buf);
- sprintf(buf, "BASE SCALER: %d", priv->regs->scaler_reload);
- print_line(p, buf);
- sprintf(buf, "BASE FREQ: %dkHz", priv->base_freq / 1000);
- print_line(p, buf);
- sprintf(buf, "SeparateIRQ: %s", priv->separate_interrupt ? "YES":"NO");
- print_line(p, buf);
-
- for (i=0; i<priv->timer_cnt; i++) {
- timer = &priv->timers[i];
- sprintf(buf, " - TIMER HW Index %d -", timer->tindex);
- print_line(p, buf);
- sprintf(buf, " TLIB Index: %d", timer->index);
- print_line(p, buf);
- sprintf(buf, " RELOAD REG: %d", timer->tregs->reload);
- print_line(p, buf);
- sprintf(buf, " CTRL REG: %d", timer->tregs->ctrl);
- print_line(p, buf);
- }
-
- return DRVMGR_OK;
-}
-#endif
-
-static inline struct gptimer_priv *priv_from_timer(struct gptimer_timer *t)
-{
- return (struct gptimer_priv *)
- ((unsigned int)t -
- sizeof(struct gptimer_priv) -
- t->index * sizeof(struct gptimer_timer));
-}
-
-static int gptimer_tlib_int_pend(struct tlib_dev *hand, int ack)
-{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
- unsigned int ctrl = timer->tregs->ctrl;
-
- if ((ctrl & (GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) ==
- (GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) {
- /* clear Pending IRQ ? */
- if (ack)
- timer->tregs->ctrl = ctrl & timer->irq_ack_mask;
- return 1; /* timer generated IRQ */
- } else
- return 0; /* was not timer causing IRQ */
-}
-
-void gptimer_isr(void *data)
-{
- struct gptimer_priv *priv = data;
- int i;
-
- /* Check all timers for IRQ */
- for (i=0;i<priv->timer_cnt; i++) {
- if (gptimer_tlib_int_pend((void *)&priv->timers[i], 0)) {
- /* IRQ Was generated by Timer and Pending flag has *not*
- * yet been cleared, this is to allow ISR to look at
- * pending bit. Call ISR registered. Clear pending bit.
- */
- if (priv->timers[i].tdev.isr_func) {
- priv->timers[i].tdev.isr_func(
- priv->timers[i].tdev.isr_data);
- }
- gptimer_tlib_int_pend((void *)&priv->timers[i], 1);
- }
- }
-}
-
-static void gptimer_tlib_reset(struct tlib_dev *hand)
-{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
-
- timer->tregs->ctrl = (timer->tregs->ctrl & timer->irq_ack_mask) &
- GPTIMER_CTRL_IP;
- timer->tregs->reload = 0xffffffff;
- timer->tregs->ctrl = GPTIMER_CTRL_LD;
-}
-
-static void gptimer_tlib_get_freq(
- struct tlib_dev *hand,
- unsigned int *basefreq,
- unsigned int *tickrate)
-{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
- struct gptimer_priv *priv = priv_from_timer(timer);
-
- /* Calculate base frequency from Timer Clock and Prescaler */
- if ( basefreq )
- *basefreq = priv->base_freq;
- if ( tickrate )
- *tickrate = timer->tregs->reload + 1;
-}
-
-static int gptimer_tlib_set_freq(struct tlib_dev *hand, unsigned int tickrate)
-{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
-
- timer->tregs->reload = tickrate - 1;
-
- /*Check that value was allowed (Timer may not be as wide as expected)*/
- if ( timer->tregs->reload != (tickrate - 1) )
- return -1;
- else
- return 0;
-}
-
-static void gptimer_tlib_irq_reg(struct tlib_dev *hand, tlib_isr_t func, void *data, int flags)
-{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
- struct gptimer_priv *priv = priv_from_timer(timer);
-
- if ( priv->separate_interrupt ) {
- drvmgr_interrupt_register(priv->dev, timer->tindex,
- "gptimer", func, data);
- } else {
- if (priv->isr_installed == 0) {
- /* Shared IRQ handler */
- drvmgr_interrupt_register(
- priv->dev,
- 0,
- "gptimer_shared",
- gptimer_isr,
- priv);
- }
- priv->isr_installed++;
- }
-
-#if RTEMS_SMP
- if (flags & TLIB_FLAGS_BROADCAST) {
- int tindex = 0;
-
- if (priv->separate_interrupt) {
- /* Offset interrupt number with HW subtimer index */
- tindex = timer->tindex;
- }
- drvmgr_interrupt_set_affinity(priv->dev, tindex,
- _SMP_Get_online_processors());
- }
-#endif
-
- timer->tregs->ctrl |= GPTIMER_CTRL_IE;
-}
-
-static void gptimer_tlib_irq_unreg(struct tlib_dev *hand, tlib_isr_t func, void *data)
-{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
- struct gptimer_priv *priv = priv_from_timer(timer);
-
- /* Turn off IRQ at source, unregister IRQ handler */
- timer->tregs->ctrl &= ~GPTIMER_CTRL_IE;
-
- if ( priv->separate_interrupt ) {
- drvmgr_interrupt_unregister(priv->dev, timer->tindex,
- func, data);
- } else {
- timer->tdev.isr_func = NULL;
- priv->isr_installed--;
- if (priv->isr_installed == 0) {
- drvmgr_interrupt_unregister(priv->dev, 0,
- gptimer_isr, priv);
- }
- }
-}
-
-static void gptimer_tlib_start(struct tlib_dev *hand, int once)
-{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
- unsigned int ctrl;
-
- /* Load the selected frequency before starting Frequency */
- ctrl = GPTIMER_CTRL_LD | GPTIMER_CTRL_EN;
- if ( once == 0 )
- ctrl |= GPTIMER_CTRL_RS; /* Restart Timer */
- timer->tregs->ctrl = ctrl | (timer->tregs->ctrl & timer->irq_ack_mask &
- ~GPTIMER_CTRL_RS);
-}
-
-static void gptimer_tlib_stop(struct tlib_dev *hand)
-{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
-
- /* Load the selected Frequency */
- timer->tregs->ctrl &= ~(GPTIMER_CTRL_EN|GPTIMER_CTRL_IP);
-}
-
-static void gptimer_tlib_restart(struct tlib_dev *hand)
-{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
-
- timer->tregs->ctrl |= GPTIMER_CTRL_LD | GPTIMER_CTRL_EN;
-}
-
-static void gptimer_tlib_get_counter(
- struct tlib_dev *hand,
- unsigned int *counter)
-{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
-
- *counter = timer->tregs->value;
-}
-
-static void gptimer_tlib_get_widthmask(
- struct tlib_dev *hand,
- unsigned int *widthmask)
-{
- struct gptimer_timer *timer = (struct gptimer_timer *)hand;
- struct gptimer_priv *priv = priv_from_timer(timer);
-
- *widthmask = priv->widthmask;
-}
-
-static struct tlib_drv gptimer_tlib_drv =
-{
- .reset = gptimer_tlib_reset,
- .get_freq = gptimer_tlib_get_freq,
- .set_freq = gptimer_tlib_set_freq,
- .irq_reg = gptimer_tlib_irq_reg,
- .irq_unreg = gptimer_tlib_irq_unreg,
- .start = gptimer_tlib_start,
- .stop = gptimer_tlib_stop,
- .restart = gptimer_tlib_restart,
- .get_counter = gptimer_tlib_get_counter,
- .custom = NULL,
- .int_pend = gptimer_tlib_int_pend,
- .get_widthmask = gptimer_tlib_get_widthmask,
-};
diff --git a/c/src/lib/libbsp/sparc/shared/timer/tlib.c b/c/src/lib/libbsp/sparc/shared/timer/tlib.c
deleted file mode 100644
index a0525d072d..0000000000
--- a/c/src/lib/libbsp/sparc/shared/timer/tlib.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Timer Library (TLIB)
- *
- * COPYRIGHT (c) 2011.
- * 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 <rtems.h>
-#include <bsp/tlib.h>
-
-struct tlib_dev *tlib_dev_head = NULL;
-struct tlib_dev *tlib_dev_tail = NULL;
-static int tlib_dev_cnt = 0;
-
-/* Register Timer device to Timer Library */
-int tlib_dev_reg(struct tlib_dev *newdev)
-{
- /* Reset device */
- newdev->status = 0;
- newdev->isr_func = NULL;
- newdev->index = tlib_dev_cnt;
-
- /* Insert last in queue */
- newdev->next = NULL;
- if ( tlib_dev_tail == NULL ) {
- tlib_dev_head = newdev;
- } else {
- tlib_dev_tail->next = newdev;
- }
- tlib_dev_tail = newdev;
-
- /* Return Index of Registered Timer */
- return tlib_dev_cnt++;
-}
-
-void *tlib_open(int timer_no)
-{
- struct tlib_dev *dev;
-
- if ( timer_no < 0 )
- return NULL;
-
- dev = tlib_dev_head;
- while ( (timer_no > 0) && dev ) {
- timer_no--;
- dev = dev->next;
- }
- if ( dev ) {
- if ( dev->status )
- return NULL;
- dev->status = 1;
- /* Reset Timer to initial state */
- tlib_reset(dev);
- }
- return dev;
-}
-
-void tlib_close(void *hand)
-{
- struct tlib_dev *dev = hand;
-
- /* Stop any ongoing timer operation and unregister IRQ if registered */
- tlib_stop(dev);
- tlib_irq_unregister(dev);
-
- /* Mark not open */
- dev->status = 0;
-}
-
-int tlib_ntimer(void)
-{
- return tlib_dev_cnt;
-}
diff --git a/c/src/lib/libbsp/sparc/shared/timer/tlib_ckinit.c b/c/src/lib/libbsp/sparc/shared/timer/tlib_ckinit.c
deleted file mode 100644
index 3f56d725d9..0000000000
--- a/c/src/lib/libbsp/sparc/shared/timer/tlib_ckinit.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Clock Tick Device Driver using Timer Library implemented
- * by the GRLIB GPTIMER / LEON2 Timer drivers.
- *
- * COPYRIGHT (c) 2010 - 2017.
- * 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.
- *
- */
-
-/*
- * This is an implementation of the RTEMS "clockdrv_shell" interface for
- * LEON2/3/4 systems using the Driver Manager. It is clock hardware agnostic
- * and compatible with SMP and UP. Availability of free running counters is
- * probed and selected as needed.
- */
-#include <rtems.h>
-#include <rtems/timecounter.h>
-#include <rtems/clockdrv.h>
-#include <stdlib.h>
-#include <bsp.h>
-#include <bsp/tlib.h>
-
-#ifdef RTEMS_DRVMGR_STARTUP
-
-#if defined(LEON3)
-#include <leon.h>
-#endif
-
-struct ops {
- /*
- * Set up the free running counter using the Timecounter or Simple
- * Timecounter interface.
- */
- rtems_device_driver (*initialize_counter)(void);
-
- /*
- * Hardware-specific support at tick interrupt which runs early in Clock_isr.
- * It can for example be used to check if interrupt was actually caused by
- * the timer hardware. If return value is not RTEMS_SUCCESSFUL then Clock_isr
- * returns immediately. at_tick can be initialized with NULL.
- */
- rtems_device_driver (*at_tick)(void);
-
- /*
- * Typically calls rtems_timecounter_tick(). A specialized clock driver may
- * use for example rtems_timecounter_tick_simple() instead.
- */
- void (*timecounter_tick)(void);
-
- /*
- * Called when the clock driver exits. It can be used to stop functionality
- * started by initialize_counter. The tick timer is stopped by default.
- * shutdown_hardware can be initialized with NULL
- */
- void (*shutdown_hardware)(void);
-};
-
-/*
- * Different implementation depending on available free running counter for the
- * timecounter.
- *
- * NOTE: The clock interface is not compatible with shared interrupts on the
- * clock (tick) timer in SMP configuration.
- */
-
-/* "simple timecounter" interface. Only for non-SMP. */
-static const struct ops ops_simple;
-/* Hardware support up-counter using LEON3 %asr23. */
-static const struct ops ops_timetag;
-/* Timestamp counter available in some IRQ(A)MP instantiations. */
-static const struct ops ops_irqamp;
-/* Separate GPTIMER subtimer as timecounter */
-static const struct ops ops_subtimer;
-
-struct clock_priv {
- const struct ops *ops;
- /*
- * Timer number in Timer Library for tick timer used by this interface.
- * Defaults to the first Timer in the System.
- */
- int tlib_tick_index;
- /* Timer number for timecounter timer if separate GPTIMER subtimer is used */
- int tlib_counter_index;
- void *tlib_tick;
- void *tlib_counter;
- rtems_timecounter_simple tc_simple;
- struct timecounter tc;
-};
-static struct clock_priv priv;
-
-/** Common interface **/
-
-/* Set system clock timer instance */
-void Clock_timer_register(int timer_number)
-{
- priv.tlib_tick_index = timer_number;
- priv.tlib_counter_index = timer_number + 1;
-}
-
-static rtems_device_driver tlib_clock_find_timer(void)
-{
- /* Take Timer that should be used as system timer. */
- priv.tlib_tick = tlib_open(priv.tlib_tick_index);
- if (priv.tlib_tick == NULL) {
- /* System Clock Timer not found */
- return RTEMS_NOT_DEFINED;
- }
-
- /* Select which operation set to use */
-#ifndef RTEMS_SMP
- priv.ops = &ops_simple;
-#else
- /* When on LEON3 try to use dedicated hardware free running counter. */
- leon3_up_counter_enable();
- if (leon3_up_counter_is_available()) {
- priv.ops = &ops_timetag;
- return RTEMS_SUCCESSFUL;
- } else {
- volatile struct irqmp_timestamp_regs *irqmp_ts;
-
- irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
- if (leon3_irqmp_has_timestamp(irqmp_ts)) {
- priv.ops = &ops_irqamp;
- return RTEMS_SUCCESSFUL;
- }
- }
-
- /* Take another subtimer as the final option. */
- priv.ops = &ops_subtimer;
-#endif
-
- return RTEMS_SUCCESSFUL;
-}
-
-static rtems_device_driver tlib_clock_initialize_hardware(void)
-{
- /* Set tick rate in number of "Base-Frequency ticks" */
- tlib_set_freq(priv.tlib_tick, rtems_configuration_get_microseconds_per_tick());
- priv.ops->initialize_counter();
- tlib_start(priv.tlib_tick, 0);
-
- return RTEMS_SUCCESSFUL;
-}
-
-static rtems_device_driver tlib_clock_at_tick(void)
-{
- if (priv.ops->at_tick) {
- return priv.ops->at_tick();
- }
-
- return RTEMS_SUCCESSFUL;
-}
-
-static void tlib_clock_timecounter_tick(void)
-{
- priv.ops->timecounter_tick();
-}
-
-/* Return a value not equal to RTEMS_SUCCESFUL to make Clock_initialize fail. */
-static rtems_device_driver tlib_clock_install_isr(rtems_isr *isr)
-{
- int flags = 0;
-
-#ifdef RTEMS_SMP
- /* We shall broadcast the clock interrupt to all processors. */
- flags = TLIB_FLAGS_BROADCAST;
-#endif
- tlib_irq_register(priv.tlib_tick, isr, NULL, flags);
-
- return RTEMS_SUCCESSFUL;
-}
-
-static void tlib_clock_shutdown_hardware(void)
-{
- if (priv.tlib_tick) {
- tlib_stop(priv.tlib_tick);
- priv.tlib_tick = NULL;
- }
- if (priv.ops->shutdown_hardware) {
- priv.ops->shutdown_hardware();
- }
-}
-
-/** Simple counter **/
-static uint32_t simple_tlib_tc_get(rtems_timecounter_simple *tc)
-{
- unsigned int clicks = 0;
-
- if (priv.tlib_tick != NULL) {
- tlib_get_counter(priv.tlib_tick, &clicks);
- }
-
- return clicks;
-}
-
-static bool simple_tlib_tc_is_pending(rtems_timecounter_simple *tc)
-{
- bool pending = false;
-
- if (priv.tlib_tick != NULL) {
- pending = tlib_interrupt_pending(priv.tlib_tick, 0) != 0;
- }
-
- return pending;
-}
-
-static uint32_t simple_tlib_tc_get_timecount(struct timecounter *tc)
-{
- return rtems_timecounter_simple_downcounter_get(
- tc,
- simple_tlib_tc_get,
- simple_tlib_tc_is_pending
- );
-}
-
-static rtems_device_driver simple_initialize_counter(void)
-{
- uint64_t frequency;
- unsigned int tick_hz;
-
- frequency = 1000000;
- tick_hz = rtems_configuration_get_microseconds_per_tick();
-
- rtems_timecounter_simple_install(
- &priv.tc_simple,
- frequency,
- tick_hz,
- simple_tlib_tc_get_timecount
- );
-
- return RTEMS_NOT_DEFINED;
-}
-
-static void simple_tlib_tc_at_tick(rtems_timecounter_simple *tc)
-{
- /* Nothing to do */
-}
-
-/*
- * Support for shared interrupts. Ack IRQ at source, only handle interrupts
- * generated from the tick-timer. This is called early in Clock_isr.
- */
-static rtems_device_driver simple_at_tick(void)
-{
- if (tlib_interrupt_pending(priv.tlib_tick, 1) == 0) {
- return RTEMS_NOT_DEFINED;
- }
- return RTEMS_SUCCESSFUL;
-}
-
-static void simple_timecounter_tick(void)
-{
- rtems_timecounter_simple_downcounter_tick(
- &priv.tc_simple,
- simple_tlib_tc_get,
- simple_tlib_tc_at_tick
- );
-}
-
-static const struct ops ops_simple = {
- .initialize_counter = simple_initialize_counter,
- .at_tick = simple_at_tick,
- .timecounter_tick = simple_timecounter_tick,
- .shutdown_hardware = NULL,
-};
-
-/** Subtimer as counter **/
-static uint32_t subtimer_get_timecount(struct timecounter *tc)
-{
- unsigned int counter;
-
- tlib_get_counter(priv.tlib_counter, &counter);
-
- return 0xffffffff - counter;
-}
-
-static rtems_device_driver subtimer_initialize_counter(void)
-{
- unsigned int mask;
- unsigned int basefreq;
-
- if (priv.tlib_counter_index == priv.tlib_tick_index) {
- priv.tlib_counter_index = priv.tlib_tick_index + 1;
- }
- /* Take Timer that should be used as timecounter upcounter timer. */
- priv.tlib_counter = tlib_open(priv.tlib_counter_index);
- if (priv.tlib_counter == NULL) {
- /* Timecounter timer not found */
- return RTEMS_NOT_DEFINED;
- }
-
- /* Configure free running counter: GPTIMER */
- tlib_get_freq(priv.tlib_counter, &basefreq, NULL);
- tlib_get_widthmask(priv.tlib_counter, &mask);
-
- priv.tc.tc_get_timecount = subtimer_get_timecount;
- priv.tc.tc_counter_mask = mask;
- priv.tc.tc_frequency = basefreq;
- priv.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
- rtems_timecounter_install(&priv.tc);
- /* Start free running counter */
- tlib_start(priv.tlib_counter, 0);
-
- return RTEMS_SUCCESSFUL;
-}
-
-static void subtimer_timecounter_tick(void)
-{
- rtems_timecounter_tick();
-}
-
-static void subtimer_shutdown_hardware(void)
-{
- if (priv.tlib_counter) {
- tlib_stop(priv.tlib_counter);
- priv.tlib_counter = NULL;
- }
-}
-
-static const struct ops ops_subtimer = {
- .initialize_counter = subtimer_initialize_counter,
- .timecounter_tick = subtimer_timecounter_tick,
- .shutdown_hardware = subtimer_shutdown_hardware,
-};
-
-#if defined(LEON3)
-/** DSU timetag as counter **/
-static uint32_t timetag_get_timecount(struct timecounter *tc)
-{
- return leon3_up_counter_low();
-}
-
-static rtems_device_driver timetag_initialize_counter(void)
-{
- /* Configure free running counter: timetag */
- priv.tc.tc_get_timecount = timetag_get_timecount;
- priv.tc.tc_counter_mask = 0xffffffff;
- priv.tc.tc_frequency = leon3_up_counter_frequency();
- priv.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
- rtems_timecounter_install(&priv.tc);
-
- return RTEMS_SUCCESSFUL;
-}
-
-static void timetag_timecounter_tick(void)
-{
- rtems_timecounter_tick();
-}
-
-static const struct ops ops_timetag = {
- .initialize_counter = timetag_initialize_counter,
- .at_tick = NULL,
- .timecounter_tick = timetag_timecounter_tick,
- .shutdown_hardware = NULL,
-};
-#endif
-
-#if defined(LEON3)
-/** IRQ(A)MP timestamp as counter **/
-static uint32_t irqamp_get_timecount(struct timecounter *tc)
-{
- return LEON3_IrqCtrl_Regs->timestamp[0].counter;
-}
-
-static rtems_device_driver irqamp_initialize_counter(void)
-{
- volatile struct irqmp_timestamp_regs *irqmp_ts;
- static const uint32_t A_TSISEL_FIELD = 0xf;
-
- /* Configure free running counter: timetag */
- priv.tc.tc_get_timecount = irqamp_get_timecount;
- priv.tc.tc_counter_mask = 0xffffffff;
- priv.tc.tc_frequency = leon3_up_counter_frequency();
- priv.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
- rtems_timecounter_install(&priv.tc);
-
- /*
- * The counter increments whenever a TSISEL field in a Timestamp Control
- * Register is non-zero.
- */
- irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
- irqmp_ts->control = A_TSISEL_FIELD;
-
- return RTEMS_SUCCESSFUL;
-}
-
-static void irqamp_timecounter_tick(void)
-{
- rtems_timecounter_tick();
-}
-
-static const struct ops ops_irqamp = {
- .initialize_counter = irqamp_initialize_counter,
- .at_tick = NULL,
- .timecounter_tick = irqamp_timecounter_tick,
- .shutdown_hardware = NULL,
-};
-#endif
-
-/** Interface to the Clock Driver Shell (dev/clock/clockimpl.h) **/
-#define Clock_driver_support_find_timer() \
- do { \
- rtems_device_driver ret; \
- ret = tlib_clock_find_timer(); \
- if (RTEMS_SUCCESSFUL != ret) { \
- return ret; \
- } \
- } while (0)
-
-#define Clock_driver_support_install_isr( isr ) \
- do { \
- rtems_device_driver ret; \
- ret = tlib_clock_install_isr( isr ); \
- if (RTEMS_SUCCESSFUL != ret) { \
- return ret; \
- } \
- } while (0)
-
-#define Clock_driver_support_set_interrupt_affinity(online_processors) \
- /* Done by tlib_clock_install_isr() */
-
-#define Clock_driver_support_initialize_hardware() \
- do { \
- rtems_device_driver ret; \
- ret = tlib_clock_initialize_hardware(); \
- if (RTEMS_SUCCESSFUL != ret) { \
- return ret; \
- } \
- } while (0)
-
-#define Clock_driver_support_shutdown_hardware() \
- tlib_clock_shutdown_hardware()
-
-#define Clock_driver_timecounter_tick() \
- tlib_clock_timecounter_tick()
-
-#define Clock_driver_support_at_tick() \
- do { \
- rtems_device_driver ret; \
- ret = tlib_clock_at_tick(); \
- if (RTEMS_SUCCESSFUL != ret) { \
- return; \
- } \
- } while (0)
-
-#include "../../../shared/dev/clock/clockimpl.h"
-
-#endif /* RTEMS_DRVMGR_STARTUP */
-