From d85c505ab0d9699600b3e5724a4badf6dbc1314b Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 19 Jul 2021 09:26:33 +0200 Subject: bsp/leon3: Use new GPTIMER register block API --- bsps/shared/grlib/btimer/gptimer.c | 178 +++++++++++++++++------------------ bsps/sparc/leon3/btimer/btimer.c | 13 ++- bsps/sparc/leon3/btimer/watchdog.c | 27 +++--- bsps/sparc/leon3/clock/ckinit.c | 33 ++++--- bsps/sparc/leon3/include/bsp/leon3.h | 44 ++++++++- bsps/sparc/leon3/include/leon.h | 24 ----- bsps/sparc/leon3/start/amba.c | 9 +- bsps/sparc/leon3/start/bspdelay.c | 8 +- bsps/sparc/leon3/start/cpucounter.c | 20 ++-- 9 files changed, 189 insertions(+), 167 deletions(-) diff --git a/bsps/shared/grlib/btimer/gptimer.c b/bsps/shared/grlib/btimer/gptimer.c index f31b7c052f..cbf058ccef 100644 --- a/bsps/shared/grlib/btimer/gptimer.c +++ b/bsps/shared/grlib/btimer/gptimer.c @@ -50,18 +50,15 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include #include #include -#include #include +#include +#include #include #if defined(LEON3) -#include +#include #endif #ifdef GPTIMER_INFO_AVAIL @@ -75,49 +72,21 @@ #include -/* 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<businfo; @@ -215,12 +184,12 @@ int gptimer_init1(struct drvmgr_dev *dev) return -1; } pnpinfo = &ambadev->info; - regs = (struct gptimer_regs *)pnpinfo->apb_slv->start; + regs = (gptimer *)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; + timer_hw_cnt = GPTIMER_CONFIG_TIMERS_GET(grlib_load_32(®s->config)); /* Let user spelect a range of timers to be used. In AMP systems * it is sometimes neccessary to leave timers for other CPU instances. @@ -251,7 +220,7 @@ int gptimer_init1(struct drvmgr_dev *dev) * are present. */ size = sizeof(struct gptimer_priv) + - timer_cnt*sizeof(struct gptimer_timer); + timer_cnt*sizeof(struct gptimer_timer_priv); priv = dev->priv = grlib_calloc(1, size); if ( !priv ) return DRVMGR_NOMEM; @@ -277,24 +246,24 @@ int gptimer_init1(struct drvmgr_dev *dev) */ value = drvmgr_dev_key_get(priv->dev, "prescaler", DRVMGR_KT_INT); if ( value ) - regs->scaler_reload = value->i; + grlib_store_32(®s->sreload, value->i); /* Get Frequency that the timers are operating in (after prescaler) */ - priv->base_freq = priv->base_clk / (priv->regs->scaler_reload + 1); + priv->base_freq = priv->base_clk / (grlib_load_32(®s->sreload) + 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; + grlib_store_32(®s->timer[timer_start].tctrl, GPTIMER_TCTRL_IP); + if ((grlib_load_32(®s->timer[timer_start].tctrl) & GPTIMER_TCTRL_IP) != 0) + irq_ack_mask = ~GPTIMER_TCTRL_IP; else - irq_ack_mask = ~0; + irq_ack_mask = ~0U; /* Probe timer register width mask */ - priv->regs->timer[timer_start].value = 0xffffffff; - priv->widthmask = priv->regs->timer[timer_start].value; + grlib_store_32(®s->timer[timer_start].tcntval, 0xffffffff); + priv->widthmask = grlib_load_32(®s->timer[timer_start].tcntval); priv->timer_cnt = timer_cnt; for (i=0; iseparate_interrupt = (regs->cfg & GPTIMER_CFG_SI) != 0; + priv->separate_interrupt = (grlib_load_32(®s->config) & GPTIMER_CONFIG_SI) != 0; return DRVMGR_OK; } @@ -326,7 +295,7 @@ static int gptimer_info( void *p, int argc, char *argv[]) { struct gptimer_priv *priv = dev->priv; - struct gptimer_timer *timer; + struct gptimer_timer_priv *timer; char buf[64]; int i; @@ -337,7 +306,7 @@ static int gptimer_info( 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); + sprintf(buf, "BASE SCALER: %d", grlib_load_32(&priv->regs->sreload)); print_line(p, buf); sprintf(buf, "BASE FREQ: %dkHz", priv->base_freq / 1000); print_line(p, buf); @@ -350,9 +319,9 @@ static int gptimer_info( print_line(p, buf); sprintf(buf, " TLIB Index: %d", timer->index); print_line(p, buf); - sprintf(buf, " RELOAD REG: %d", timer->tregs->reload); + sprintf(buf, " RELOAD REG: %d", grlib_load_32(&timer->tregs->trldval)); print_line(p, buf); - sprintf(buf, " CTRL REG: %d", timer->tregs->ctrl); + sprintf(buf, " CTRL REG: %d", grlib_load_32(&timer->tregs->tctrl)); print_line(p, buf); } @@ -360,24 +329,28 @@ static int gptimer_info( } #endif -static inline struct gptimer_priv *priv_from_timer(struct gptimer_timer *t) +static inline struct gptimer_priv *priv_from_timer(struct gptimer_timer_priv *t) { return (struct gptimer_priv *) ((unsigned int)t - sizeof(struct gptimer_priv) - - t->index * sizeof(struct gptimer_timer)); + t->index * sizeof(struct gptimer_timer_priv)); } 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; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; + + tctrl = grlib_load_32(&timer->tregs->tctrl); - if ((ctrl & (GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) == - (GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) { + if ((tctrl & (GPTIMER_TCTRL_IP | GPTIMER_TCTRL_IE)) == + (GPTIMER_TCTRL_IP | GPTIMER_TCTRL_IE)) { /* clear Pending IRQ ? */ - if (ack) - timer->tregs->ctrl = ctrl & timer->irq_ack_mask; + if (ack) { + tctrl &= timer->irq_ack_mask; + grlib_store_32(&timer->tregs->tctrl, tctrl); + } return 1; /* timer generated IRQ */ } else return 0; /* was not timer causing IRQ */ @@ -406,12 +379,15 @@ void gptimer_isr(void *data) 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; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; + + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl &= timer->irq_ack_mask; + tctrl &= GPTIMER_TCTRL_IP; + grlib_store_32(&timer->tregs->tctrl, tctrl); + grlib_store_32(&timer->tregs->trldval, 0xffffffff); + grlib_store_32(&timer->tregs->tctrl, GPTIMER_TCTRL_LD); } static void gptimer_tlib_get_freq( @@ -419,24 +395,24 @@ static void gptimer_tlib_get_freq( unsigned int *basefreq, unsigned int *tickrate) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)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; + *tickrate = grlib_load_32(&timer->tregs->trldval) + 1; } static int gptimer_tlib_set_freq(struct tlib_dev *hand, unsigned int tickrate) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; - timer->tregs->reload = tickrate - 1; + grlib_store_32(&timer->tregs->trldval, tickrate - 1); /*Check that value was allowed (Timer may not be as wide as expected)*/ - if ( timer->tregs->reload != (tickrate - 1) ) + if (grlib_load_32(&timer->tregs->trldval) != (tickrate - 1)) return -1; else return 0; @@ -444,8 +420,9 @@ static int gptimer_tlib_set_freq(struct tlib_dev *hand, unsigned int tickrate) 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_timer_priv *timer = (struct gptimer_timer_priv *)hand; struct gptimer_priv *priv = priv_from_timer(timer); + uint32_t tctrl; if ( priv->separate_interrupt ) { drvmgr_interrupt_register(priv->dev, timer->tindex, @@ -476,16 +453,21 @@ static void gptimer_tlib_irq_reg(struct tlib_dev *hand, tlib_isr_t func, void *d } #endif - timer->tregs->ctrl |= GPTIMER_CTRL_IE; + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl |= GPTIMER_TCTRL_IE; + grlib_store_32(&timer->tregs->tctrl, tctrl); } 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_timer_priv *timer = (struct gptimer_timer_priv *)hand; struct gptimer_priv *priv = priv_from_timer(timer); + uint32_t tctrl; /* Turn off IRQ at source, unregister IRQ handler */ - timer->tregs->ctrl &= ~GPTIMER_CTRL_IE; + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl &= ~GPTIMER_TCTRL_IE; + grlib_store_32(&timer->tregs->tctrl, tctrl); if ( priv->separate_interrupt ) { drvmgr_interrupt_unregister(priv->dev, timer->tindex, @@ -502,46 +484,54 @@ static void gptimer_tlib_irq_unreg(struct tlib_dev *hand, tlib_isr_t func, void static void gptimer_tlib_start(struct tlib_dev *hand, int once) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - unsigned int ctrl; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; /* Load the selected frequency before starting Frequency */ - ctrl = GPTIMER_CTRL_LD | GPTIMER_CTRL_EN; + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl &= timer->irq_ack_mask; + tctrl &= ~GPTIMER_TCTRL_RS; + tctrl |= GPTIMER_TCTRL_LD | GPTIMER_TCTRL_EN; if ( once == 0 ) - ctrl |= GPTIMER_CTRL_RS; /* Restart Timer */ - timer->tregs->ctrl = ctrl | (timer->tregs->ctrl & timer->irq_ack_mask & - ~GPTIMER_CTRL_RS); + tctrl |= GPTIMER_TCTRL_RS; /* Restart Timer */ + grlib_store_32(&timer->tregs->tctrl, tctrl); } static void gptimer_tlib_stop(struct tlib_dev *hand) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; /* Load the selected Frequency */ - timer->tregs->ctrl &= ~(GPTIMER_CTRL_EN|GPTIMER_CTRL_IP); + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl &= ~(GPTIMER_TCTRL_EN|GPTIMER_TCTRL_IP); + grlib_store_32(&timer->tregs->tctrl, tctrl); } static void gptimer_tlib_restart(struct tlib_dev *hand) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; - timer->tregs->ctrl |= GPTIMER_CTRL_LD | GPTIMER_CTRL_EN; + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl |= GPTIMER_TCTRL_LD | GPTIMER_TCTRL_EN; + grlib_store_32(&timer->tregs->tctrl, tctrl); } static void gptimer_tlib_get_counter( struct tlib_dev *hand, unsigned int *counter) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; - *counter = timer->tregs->value; + *counter = grlib_load_32(&timer->tregs->tcntval); } static void gptimer_tlib_get_widthmask( struct tlib_dev *hand, unsigned int *widthmask) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; struct gptimer_priv *priv = priv_from_timer(timer); *widthmask = priv->widthmask; diff --git a/bsps/sparc/leon3/btimer/btimer.c b/bsps/sparc/leon3/btimer/btimer.c index 9e9f2b02fc..9f2a7ede74 100644 --- a/bsps/sparc/leon3/btimer/btimer.c +++ b/bsps/sparc/leon3/btimer/btimer.c @@ -33,23 +33,21 @@ 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) { + gptimer_timer *timer = &LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX]; 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; + grlib_store_32( &timer->trldval, 0xffffff ); + grlib_store_32( &timer->tcntval, 0xffffff ); } else { benchmark_timer_is_initialized = true; } - LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].ctrl = - GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_LD; + grlib_store_32( &timer->tctrl, GPTIMER_TCTRL_EN | GPTIMER_TCTRL_LD ); } } @@ -62,7 +60,8 @@ benchmark_timer_t benchmark_timer_read(void) uint32_t total; if (LEON3_Timer_Regs) { - total = LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].value; + total = + grlib_load_32( &LEON3_Timer_Regs->timer[LEON3_TIMER_INDEX].tcntval ); total = 0xffffff - total; diff --git a/bsps/sparc/leon3/btimer/watchdog.c b/bsps/sparc/leon3/btimer/watchdog.c index 8b875aa2a8..919744496f 100644 --- a/bsps/sparc/leon3/btimer/watchdog.c +++ b/bsps/sparc/leon3/btimer/watchdog.c @@ -30,14 +30,12 @@ */ #include +#include #include -#include - -extern volatile struct gptimer_regs *LEON3_Timer_Regs; struct gptimer_watchdog_priv { - struct gptimer_regs *regs; - struct gptimer_timer_regs *timer; + gptimer *regs; + gptimer_timer *timer; int timerno; }; @@ -60,10 +58,10 @@ int bsp_watchdog_init(void) * 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; + bsp_watchdogs[0].regs = LEON3_Timer_Regs; /* Find Timer that has watchdog functionality */ - timercnt = bsp_watchdogs[0].regs->cfg & 0x7; + timercnt = grlib_load_32(&bsp_watchdogs[0].regs->config) & 0x7; if (timercnt < 2) /* First timer system clock timer */ return 0; @@ -76,6 +74,9 @@ int bsp_watchdog_init(void) void bsp_watchdog_reload(int watchdog, unsigned int reload_value) { + gptimer_timer *timer; + uint32_t tctrl; + if (bsp_watchdog_count == 0) bsp_watchdog_init(); @@ -83,10 +84,12 @@ void bsp_watchdog_reload(int watchdog, unsigned int reload_value) 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)); + timer = bsp_watchdogs[watchdog].timer; + grlib_store_32(&timer->trldval, reload_value); + tctrl = grlib_load_32(&timer->tctrl); + tctrl |= GPTIMER_TCTRL_LD | GPTIMER_TCTRL_EN; + tctrl &= ~GPTIMER_TCTRL_IP; + grlib_store_32(&timer->tctrl, tctrl); } void bsp_watchdog_stop(int watchdog) @@ -98,7 +101,7 @@ void bsp_watchdog_stop(int watchdog) return; /* Stop watchdog timer */ - bsp_watchdogs[watchdog].timer->ctrl = 0; + grlib_store_32(&bsp_watchdogs[watchdog].timer->tctrl, 0); } /* Use watchdog timer to reset system */ diff --git a/bsps/sparc/leon3/clock/ckinit.c b/bsps/sparc/leon3/clock/ckinit.c index 613ad3509d..9f45d9814b 100644 --- a/bsps/sparc/leon3/clock/ckinit.c +++ b/bsps/sparc/leon3/clock/ckinit.c @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include #include @@ -148,7 +148,7 @@ static void leon3_tc_do_tick(void) do { \ /* Assume timer found during BSP initialization */ \ if (LEON3_Timer_Regs) { \ - clkirq = (LEON3_Timer_Regs->cfg & 0xf8) >> 3; \ + clkirq = (grlib_load_32(&LEON3_Timer_Regs->config) & 0xf8) >> 3; \ \ Adjust_clkirq_for_node(); \ } \ @@ -185,19 +185,22 @@ static void bsp_clock_handler_install(rtems_interrupt_handler isr) static void leon3_clock_initialize(void) { irqamp_timestamp *irqmp_ts; - volatile struct gptimer_regs *gpt; + gptimer_timer *timer; struct timecounter *tc; - irqmp_ts = irqamp_get_timestamp_registers(LEON3_IrqCtrl_Regs); - gpt = LEON3_Timer_Regs; - tc = &leon3_tc; + timer = &LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX]; - gpt->timer[LEON3_CLOCK_INDEX].reload = - rtems_configuration_get_microseconds_per_tick() - 1; - gpt->timer[LEON3_CLOCK_INDEX].ctrl = - GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_RS | - GPTIMER_TIMER_CTRL_LD | GPTIMER_TIMER_CTRL_IE; + grlib_store_32( + &timer->trldval, + rtems_configuration_get_microseconds_per_tick() - 1 + ); + grlib_store_32( + &timer->tctrl, + GPTIMER_TCTRL_EN | GPTIMER_TCTRL_RS | GPTIMER_TCTRL_LD | GPTIMER_TCTRL_IE + ); + irqmp_ts = irqamp_get_timestamp_registers(LEON3_IrqCtrl_Regs); + tc = &leon3_tc; leon3_up_counter_enable(); if (leon3_up_counter_is_available()) { @@ -231,8 +234,10 @@ static void leon3_clock_initialize(void) * controller. At least on SMP configurations we must use a second timer * in free running mode for the timecounter. */ - gpt->timer[LEON3_COUNTER_GPTIMER_INDEX].ctrl = - GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_IE; + grlib_store_32( + &LEON3_Timer_Regs->timer[LEON3_COUNTER_GPTIMER_INDEX].tctrl, + GPTIMER_TCTRL_EN | GPTIMER_TCTRL_IE + ); tc->tc_get_timecount = _SPARC_Get_timecount_down; #else @@ -241,7 +246,7 @@ static void leon3_clock_initialize(void) counter = &_SPARC_Counter_mutable; counter->read_isr_disabled = _SPARC_Counter_read_clock_isr_disabled; counter->read = _SPARC_Counter_read_clock; - counter->counter_register = &gpt->timer[LEON3_CLOCK_INDEX].value; + counter->counter_register = &timer->tcntval; counter->pending_register = grlib_load_32(&LEON3_IrqCtrl_Regs->ipend); counter->pending_mask = UINT32_C(1) << clkirq; counter->accumulated = rtems_configuration_get_microseconds_per_tick(); diff --git a/bsps/sparc/leon3/include/bsp/leon3.h b/bsps/sparc/leon3/include/bsp/leon3.h index 75abc34fb7..aa3898e530 100644 --- a/bsps/sparc/leon3/include/bsp/leon3.h +++ b/bsps/sparc/leon3/include/bsp/leon3.h @@ -9,7 +9,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH & Co. KG + * Copyright (C) 2014, 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,6 +37,7 @@ #define LIBBSP_SPARC_LEON3_BSP_LEON3_H #include +#include #include @@ -151,6 +152,47 @@ static inline uint32_t leon3_get_data_cache_config_register( void ) return leon3_get_system_register( 0xc ); } +/** + * @brief This constant defines the index of the GPTIMER timer used by the + * clock driver. + */ +#if defined(RTEMS_MULTIPROCESSING) +#define LEON3_CLOCK_INDEX \ + ( rtems_configuration_get_user_multiprocessing_table() ? LEON3_Cpu_Index : 0 ) +#else +#define LEON3_CLOCK_INDEX 0 +#endif + +/** + * @brief This constant defines the index of the GPTIMER timer used by the + * CPU counter if the CPU counter uses the GPTIMER. + */ +#if defined(RTEMS_SMP) +#define LEON3_COUNTER_GPTIMER_INDEX ( LEON3_CLOCK_INDEX + 1 ) +#else +#define LEON3_COUNTER_GPTIMER_INDEX LEON3_CLOCK_INDEX +#endif + +/** + * @brief This constant defines the frequency set by the boot loader of the + * first GPTIMER instance. + * + * We assume that a boot loader (usually GRMON) initialized the GPTIMER 0 to + * run with 1MHz. This is used to determine all clock frequencies of the PnP + * devices. See also ambapp_freq_init() and ambapp_freq_get(). + */ +#define LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER 1000000 + +/** + * @brief This pointer provides the GPTIMER register block address. + */ +extern gptimer *LEON3_Timer_Regs; + +/** + * @brief This pointer provides the GPTIMER device information block. + */ +extern struct ambapp_dev *LEON3_Timer_Adev; + /** * @brief Gets the LEON up-counter low register (%ASR23) value. * diff --git a/bsps/sparc/leon3/include/leon.h b/bsps/sparc/leon3/include/leon.h index 3d7ce03f2a..f5f6fa84e4 100644 --- a/bsps/sparc/leon3/include/leon.h +++ b/bsps/sparc/leon3/include/leon.h @@ -142,10 +142,6 @@ extern "C" { #define LEON_REG_UART_CTRL_FA 0x80000000 /* FIFO Available */ #define LEON_REG_UART_CTRL_FA_BIT 31 -/* LEON3 GP Timer */ -extern volatile struct gptimer_regs *LEON3_Timer_Regs; -extern struct ambapp_dev *LEON3_Timer_Adev; - /* Macros used for manipulating bits in LEON3 GP Timer Control Register */ #define LEON3_IRQMPSTATUS_CPUNR 28 @@ -316,26 +312,6 @@ extern struct ambapp_dev *LEON3_Timer_Adev; #define LEON_REG_TIMER_COUNTER_DEFINED_MASK 0x00000003 #define LEON_REG_TIMER_COUNTER_CURRENT_MODE_MASK 0x00000003 -#if defined(RTEMS_MULTIPROCESSING) - #define LEON3_CLOCK_INDEX \ - (rtems_configuration_get_user_multiprocessing_table() ? LEON3_Cpu_Index : 0) -#else - #define LEON3_CLOCK_INDEX 0 -#endif - -#if defined(RTEMS_SMP) -#define LEON3_COUNTER_GPTIMER_INDEX (LEON3_CLOCK_INDEX + 1) -#else -#define LEON3_COUNTER_GPTIMER_INDEX LEON3_CLOCK_INDEX -#endif - -/* - * We assume that a boot loader (usually GRMON) initialized the GPTIMER 0 to - * run with 1MHz. This is used to determine all clock frequencies of the PnP - * devices. See also ambapp_freq_init() and ambapp_freq_get(). - */ -#define LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER 1000000 - /* Load 32-bit word by forcing a cache-miss */ static inline unsigned int leon_r32_no_cache(uintptr_t addr) { diff --git a/bsps/sparc/leon3/start/amba.c b/bsps/sparc/leon3/start/amba.c index c1e26d316c..d4494224c4 100644 --- a/bsps/sparc/leon3/start/amba.c +++ b/bsps/sparc/leon3/start/amba.c @@ -118,7 +118,8 @@ RTEMS_SYSINIT_ITEM( /* Pointers to Interrupt Controller configuration registers */ irqamp *LEON3_IrqCtrl_Regs; struct ambapp_dev *LEON3_IrqCtrl_Adev; -volatile struct gptimer_regs *LEON3_Timer_Regs; + +gptimer *LEON3_Timer_Regs; struct ambapp_dev *LEON3_Timer_Adev; /* @@ -170,14 +171,14 @@ static void amba_initialize(void) VENDOR_GAISLER, GAISLER_GPTIMER, ambapp_find_by_idx, &leon3_timer_core_index); if (adev) { - LEON3_Timer_Regs = (volatile struct gptimer_regs *)DEV_TO_APB(adev)->start; + LEON3_Timer_Regs = (gptimer *)DEV_TO_APB(adev)->start; LEON3_Timer_Adev = adev; /* Register AMBA Bus Frequency */ ambapp_freq_init( plb, LEON3_Timer_Adev, - (LEON3_Timer_Regs->scaler_reload + 1) + (grlib_load_32(&LEON3_Timer_Regs->sreload) + 1) * LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER ); /* Set user prescaler configuration. Use this to increase accuracy of timer @@ -186,7 +187,7 @@ static void amba_initialize(void) * GRTIMER/GPTIMER hardware. See HW manual. */ if (leon3_timer_prescaler) - LEON3_Timer_Regs->scaler_reload = leon3_timer_prescaler; + grlib_store_32(&LEON3_Timer_Regs->sreload, leon3_timer_prescaler); } } diff --git a/bsps/sparc/leon3/start/bspdelay.c b/bsps/sparc/leon3/start/bspdelay.c index c4a880be6d..6695f76929 100644 --- a/bsps/sparc/leon3/start/bspdelay.c +++ b/bsps/sparc/leon3/start/bspdelay.c @@ -14,15 +14,17 @@ */ #include -#include +#include void rtems_bsp_delay(int usecs) { uint32_t then; + gptimer_timer *regs; - then =LEON3_Timer_Regs->timer[0].value; + regs = &LEON3_Timer_Regs->timer[0]; + then =grlib_load_32(®s->tcntval); then += usecs; - while (LEON3_Timer_Regs->timer[0].value >= then) + while (grlib_load_32(®s->tcntval) >= then) ; } diff --git a/bsps/sparc/leon3/start/cpucounter.c b/bsps/sparc/leon3/start/cpucounter.c index 0a54ba9a74..5672cbbd45 100644 --- a/bsps/sparc/leon3/start/cpucounter.c +++ b/bsps/sparc/leon3/start/cpucounter.c @@ -25,7 +25,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include +#include #include #include @@ -42,7 +42,7 @@ uint32_t _CPU_Counter_frequency(void) static void leon3_counter_initialize(void) { irqamp_timestamp *irqmp_ts; - volatile struct gptimer_regs *gpt; + gptimer *gpt; SPARC_Counter *counter; irqmp_ts = irqamp_get_timestamp_registers(LEON3_IrqCtrl_Regs); @@ -68,19 +68,23 @@ static void leon3_counter_initialize(void) leon3_counter_frequency = ambapp_freq_get(ambapp_plb(), LEON3_IrqCtrl_Adev); } else if (gpt != NULL) { + gptimer_timer *timer; + uint32_t tctrl; + /* Fall back to the first GPTIMER if available */ + timer = &gpt->timer[LEON3_COUNTER_GPTIMER_INDEX]; counter->read_isr_disabled = _SPARC_Counter_read_down; counter->read = _SPARC_Counter_read_down; - counter->counter_register = &gpt->timer[LEON3_COUNTER_GPTIMER_INDEX].value; + counter->counter_register = &timer->tcntval; /* Enable timer just in case no clock driver is configured */ - gpt->timer[LEON3_COUNTER_GPTIMER_INDEX].reload = 0xffffffff; - gpt->timer[LEON3_COUNTER_GPTIMER_INDEX].ctrl |= GPTIMER_TIMER_CTRL_EN | - GPTIMER_TIMER_CTRL_RS | - GPTIMER_TIMER_CTRL_LD; + grlib_store_32(&timer->trldval, 0xffffffff); + tctrl = grlib_load_32(&timer->tctrl); + tctrl |= GPTIMER_TCTRL_EN | GPTIMER_TCTRL_RS | GPTIMER_TCTRL_LD; + grlib_store_32(&timer->tctrl, tctrl); leon3_counter_frequency = ambapp_freq_get(ambapp_plb(), LEON3_Timer_Adev) / - (gpt->scaler_reload + 1); + (grlib_load_32(&gpt->sreload) + 1); } } -- cgit v1.2.3