[PATCH v2 12/32] bsp/leon3: Use new GPTIMER register block API

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Jun 16 06:01:09 UTC 2023


---
 bsps/shared/grlib/btimer/gptimer.c   | 177 +++++++++++++--------------
 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, 188 insertions(+), 167 deletions(-)

diff --git a/bsps/shared/grlib/btimer/gptimer.c b/bsps/shared/grlib/btimer/gptimer.c
index f31b7c052f..ca87780d2c 100644
--- a/bsps/shared/grlib/btimer/gptimer.c
+++ b/bsps/shared/grlib/btimer/gptimer.c
@@ -50,18 +50,15 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <rtems.h>
-#include <bsp.h>
-#include <stdlib.h>
-#include <string.h>
 #include <drvmgr/drvmgr.h>
 #include <grlib/ambapp_bus.h>
-#include <grlib/grlib.h>
 #include <grlib/gptimer.h>
+#include <grlib/gptimer-regs.h>
+#include <grlib/io.h>
 #include <grlib/tlib.h>
 
 #if defined(LEON3)
-#include <leon.h>
+#include <bsp/leon3.h>
 #endif
 
 #ifdef GPTIMER_INFO_AVAIL
@@ -75,49 +72,21 @@
 
 #include <grlib/grlib_impl.h>
 
-/* 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 gptimer_timer_priv {
 	struct tlib_dev tdev;	/* Must be first in struct */
-	struct gptimer_timer_regs *tregs;
+	gptimer_timer *tregs;
 	char index; /* Timer Index in this driver */
 	char tindex; /* Timer Index In Hardware */
-	unsigned char irq_ack_mask;
+	uint32_t irq_ack_mask;
 };
 
 /* GPTIMER Core private */
 struct gptimer_priv {
 	struct drvmgr_dev *dev;
-	struct gptimer_regs *regs;
+	gptimer *regs;
 	unsigned int base_clk;
 	unsigned int base_freq;
 	unsigned int widthmask;
@@ -126,7 +95,7 @@ struct gptimer_priv {
 
 	/* Structure per Timer unit, the core supports up to 8 timers */
 	int timer_cnt;
-	struct gptimer_timer timers[0];
+	struct gptimer_timer_priv timers[0];
 };
 
 void gptimer_isr(void *data);
@@ -200,14 +169,14 @@ void gptimer_register_drv (void)
 int gptimer_init1(struct drvmgr_dev *dev)
 {
 	struct gptimer_priv *priv;
-	struct gptimer_regs *regs;
+	gptimer *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;
+	struct gptimer_timer_priv *timer;
 	union drvmgr_key_value *value;
-	unsigned char irq_ack_mask;
+	uint32_t irq_ack_mask;
 
 	/* Get device information from AMBA PnP information */
 	ambadev = (struct amba_dev_info *)dev->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(&regs->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(&regs->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(&regs->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(&regs->timer[timer_start].tctrl, GPTIMER_TCTRL_IP);
+	if ((grlib_load_32(&regs->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(&regs->timer[timer_start].tcntval, 0xffffffff);
+	priv->widthmask = grlib_load_32(&regs->timer[timer_start].tcntval);
 
 	priv->timer_cnt = timer_cnt;
 	for (i=0; i<timer_cnt; i++) {
@@ -314,7 +283,7 @@ int gptimer_init1(struct drvmgr_dev *dev)
 	 *  B. Each Timer have an individual IRQ. The number is:
 	 *        BASE_IRQ + timer_index
 	 */
-	priv->separate_interrupt = (regs->cfg & GPTIMER_CFG_SI) != 0;
+	priv->separate_interrupt = (grlib_load_32(&regs->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,14 @@ 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 | 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 +394,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 +419,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 +452,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 +483,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 <bsp.h>
+#include <bsp/leon3.h>
 #include <bsp/watchdog.h>
-#include <grlib/grlib.h>
-
-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 b3761bed35..eea598dd48 100644
--- a/bsps/sparc/leon3/clock/ckinit.c
+++ b/bsps/sparc/leon3/clock/ckinit.c
@@ -42,7 +42,7 @@
 #include <bsp.h>
 #include <bsp/fatal.h>
 #include <bsp/irq.h>
-#include <leon.h>
+#include <bsp/leon3.h>
 #include <rtems/rtems/intr.h>
 #include <grlib/ambapp.h>
 #include <grlib/irqamp.h>
@@ -144,7 +144,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(); \
     } \
@@ -181,19 +181,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()) {
@@ -227,8 +230,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
@@ -237,7 +242,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 = &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 <grlib/apbuart-regs.h>
+#include <grlib/gptimer-regs.h>
 
 #include <bsp/irqimpl.h>
 
@@ -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 6fe499989d..be3819737a 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
@@ -310,26 +306,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 <bsp.h>
-#include <leon.h>
+#include <bsp/leon3.h>
 
 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(&regs->tcntval);
   then += usecs;
 
-  while (LEON3_Timer_Regs->timer[0].value >= then)
+  while (grlib_load_32(&regs->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 <leon.h>
+#include <bsp/leon3.h>
 #include <grlib/irqamp.h>
 
 #include <rtems/counter.h>
@@ -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);
   }
 }
 
-- 
2.35.3



More information about the devel mailing list