From d6b61f9b471029ebe6179e41a5ab0df68e65f02f Mon Sep 17 00:00:00 2001
From: Armin Luntzer <armin.luntzer@univie.ac.at>
Date: Tue, 17 Jul 2018 12:54:05 +0200
Subject: [PATCH] * add GPTIMER access library * rename dev/ -> lib/ * rename
 leon_uptime_init() -> sparc_uptime_init()

---
 arch/sparc/Kbuild                           |   1 -
 arch/sparc/include/asm/time.h               |   4 +-
 arch/sparc/include/gptimer.h                |  79 +++++
 arch/sparc/kernel/setup.c                   |   2 +-
 arch/sparc/kernel/time.c                    |   2 +-
 arch/sparc/{drv => lib}/Makefile            |   0
 arch/sparc/lib/gptimer.c                    | 363 ++++++++++++++++++++
 arch/sparc/{drv => lib}/grtimer.c           |   2 +-
 arch/sparc/{drv => lib}/grtimer_longcount.c |   4 +-
 9 files changed, 449 insertions(+), 8 deletions(-)
 create mode 100644 arch/sparc/include/gptimer.h
 rename arch/sparc/{drv => lib}/Makefile (100%)
 create mode 100644 arch/sparc/lib/gptimer.c
 rename arch/sparc/{drv => lib}/grtimer.c (99%)
 rename arch/sparc/{drv => lib}/grtimer_longcount.c (98%)

diff --git a/arch/sparc/Kbuild b/arch/sparc/Kbuild
index 133d36d..082d329 100644
--- a/arch/sparc/Kbuild
+++ b/arch/sparc/Kbuild
@@ -1,3 +1,2 @@
 obj-y += kernel/
 obj-y += mm/
-obj-y += drv/
diff --git a/arch/sparc/include/asm/time.h b/arch/sparc/include/asm/time.h
index 316aaa1..87c1fc4 100644
--- a/arch/sparc/include/asm/time.h
+++ b/arch/sparc/include/asm/time.h
@@ -1,5 +1,5 @@
 /**
- * @file arch/sparc/include/time.h
+ * @file arch/sparc/include/asm/time.h
  */
 
 #ifndef _SPARC_TIME_H_
@@ -61,6 +61,6 @@ compile_time_assert((SPARC_CPU_CPS <= 1000000000UL),
 
 
 
-void leon_uptime_init(void);
+void sparc_uptime_init(void);
 
 #endif /* _SPARC_TIME_H_ */
diff --git a/arch/sparc/include/gptimer.h b/arch/sparc/include/gptimer.h
new file mode 100644
index 0000000..5b220d0
--- /dev/null
+++ b/arch/sparc/include/gptimer.h
@@ -0,0 +1,79 @@
+/**
+ * @file   arch/sparc/gptimer.h
+ * @ingroup timing
+ * @author Armin Luntzer (armin.luntzer@univie.ac.at),
+ * @date   July, 2016
+ *
+ * @copyright GPLv2
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _SPARC_GPTIMER_H
+#define _SPARC_GPTIMER_H
+
+#include <asm/leon_reg.h>
+
+
+#define LEON3_TIMER_EN	0x00000001       /* enable counting */
+#define LEON3_TIMER_RS	0x00000002       /* restart from timer reload value */
+#define LEON3_TIMER_LD	0x00000004       /* load counter    */
+#define LEON3_TIMER_IE	0x00000008       /* irq enable      */
+#define LEON3_TIMER_IP	0x00000010       /* irq pending (clear by writing 0 */
+#define LEON3_TIMER_CH	0x00000020       /* chain with preceeding timer */
+
+#define LEON3_CFG_TIMERS_MASK	0x00000007
+#define LEON3_CFG_IRQNUM_MASK	0x000000f8
+#define LEON3_CFG_IRQNUM_SHIFT	       0x3
+
+
+void gptimer_set_scaler_reload(struct gptimer_unit *ptu, uint32_t value);
+uint32_t gptimer_get_scaler_reload(struct gptimer_unit *ptu);
+
+void gptimer_set_interrupt_enabled(struct gptimer_unit *ptu, uint32_t timer);
+void gptimer_clear_interrupt_enabled(struct gptimer_unit *ptu, uint32_t timer);
+
+void gptimer_set_load(struct gptimer_unit *ptu, uint32_t timer);
+void gptimer_clear_load(struct gptimer_unit *ptu, uint32_t timer);
+
+void gptimer_set_enabled(struct gptimer_unit *ptu, uint32_t timer);
+void gptimer_clear_enabled(struct gptimer_unit *ptu, uint32_t timer);
+
+void gptimer_set_restart(struct gptimer_unit *ptu, uint32_t timer);
+void gptimer_clear_restart(struct gptimer_unit *ptu, uint32_t timer);
+
+void gptimer_set_chained(struct gptimer_unit *ptu, uint32_t timer);
+void gptimer_clear_chained(struct gptimer_unit *ptu, uint32_t timer);
+
+uint32_t gptimer_get_interrupt_pending_status(struct gptimer_unit *ptu,
+					      uint32_t timer);
+void gptimer_clear_interrupt_pending_status(struct gptimer_unit *ptu,
+					    uint32_t timer);
+
+uint32_t gptimer_get_num_implemented(struct gptimer_unit *ptu);
+uint32_t gptimer_get_first_timer_irq_id(struct gptimer_unit *ptu);
+
+void gptimer_set_value(struct gptimer_unit *ptu,
+		       uint32_t timer,
+		       uint32_t value);
+uint32_t gptimer_get_value(struct gptimer_unit *ptu, uint32_t timer);
+
+void gptimer_set_reload(struct gptimer_unit *ptu,
+			uint32_t timer,
+			uint32_t reload);
+uint32_t gptimer_get_reload(struct gptimer_unit *ptu, uint32_t timer);
+
+void gptimer_start(struct gptimer_unit *ptu, uint32_t timer, uint32_t value);
+
+void gptimer_start_cyclical(struct gptimer_unit *ptu,
+			    uint32_t timer,
+			    uint32_t value);
+
+#endif /* _SPARC_GPTIMER_H */
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 1a3edfc..84d8e7d 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -103,5 +103,5 @@ void setup_arch(void)
 
 	leon_irq_init();
 
-	leon_uptime_init();
+	sparc_uptime_init();
 }
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 5aaf9b6..2b57684 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -75,7 +75,7 @@ static struct clocksource uptime_clock = {
 };
 
 
-void leon_uptime_init(void)
+void sparc_uptime_init(void)
 {
 #ifdef CONFIG_LEON3
 	leon_grtimer_longcount_init();
diff --git a/arch/sparc/drv/Makefile b/arch/sparc/lib/Makefile
similarity index 100%
rename from arch/sparc/drv/Makefile
rename to arch/sparc/lib/Makefile
diff --git a/arch/sparc/lib/gptimer.c b/arch/sparc/lib/gptimer.c
new file mode 100644
index 0000000..9ae6768
--- /dev/null
+++ b/arch/sparc/lib/gptimer.c
@@ -0,0 +1,363 @@
+/**
+ * @file   arch/sparc/lib/gptimer.c
+ * @ingroup time
+ * @author Armin Luntzer (armin.luntzer@univie.ac.at),
+ * @date   July, 2016
+ *
+ * @copyright GPLv2
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * @brief implements access to the LEON3 General Purpose Timer Unit
+ * @see GR712RC user manual chapter 11
+ *
+ */
+
+
+#include <asm/io.h>
+#include <gptimer.h>
+
+
+/**
+ * @brief set scaler reload value of the timer block
+ * @param ptu a struct gptimer_unit
+ *
+ */
+
+void gptimer_set_scaler_reload(struct gptimer_unit *ptu, uint32_t value)
+{
+	iowrite32be(value, &ptu->scaler_reload);
+}
+
+
+/**
+ * @brief get scaler reload value of the timer block
+ * @param ptu a struct gptimer_unit
+ *
+ */
+
+uint32_t gptimer_get_scaler_reload(struct gptimer_unit *ptu)
+{
+	return ioread32be(&ptu->scaler_reload);
+}
+
+
+/**
+ * @brief sets the interrupt enabled flag of a timer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+
+void gptimer_set_interrupt_enabled(struct gptimer_unit *ptu, uint32_t timer)
+{
+	uint32_t flags;
+
+	flags  = ioread32be(&ptu->timer[timer].ctrl);
+	flags |= LEON3_TIMER_IE;
+
+	iowrite32be(flags, &ptu->timer[timer].ctrl);
+}
+
+
+/**
+ * @brief sets the interrupt enabled flag of a timer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+
+void gptimer_clear_interrupt_enabled(struct gptimer_unit *ptu, uint32_t timer)
+{
+	uint32_t flags;
+
+	flags  = ioread32be(&ptu->timer[timer].ctrl);
+	flags &= ~LEON3_TIMER_IE;
+
+	iowrite32be(flags, &ptu->timer[timer].ctrl);
+}
+
+
+/**
+ * @brief sets the load flag of a timer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+
+void gptimer_set_load(struct gptimer_unit *ptu, uint32_t timer)
+{
+	uint32_t flags;
+
+	flags  = ioread32be(&ptu->timer[timer].ctrl);
+	flags |= LEON3_TIMER_LD;
+
+	iowrite32be(flags, &ptu->timer[timer].ctrl);
+}
+
+
+/**
+ * @brief clears the load flag of a timer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+
+void gptimer_clear_load(struct gptimer_unit *ptu, uint32_t timer)
+{
+	uint32_t flags;
+
+	flags  = ioread32be(&ptu->timer[timer].ctrl);
+	flags &= ~LEON3_TIMER_LD;
+
+	iowrite32be(flags, &ptu->timer[timer].ctrl);
+}
+
+
+/**
+ * @brief set enable flag in timer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+void gptimer_set_enabled(struct gptimer_unit *ptu, uint32_t timer)
+{
+	uint32_t ctrl;
+
+	ctrl  = ioread32be(&ptu->timer[timer].ctrl);
+	ctrl |= LEON3_TIMER_EN;
+
+	iowrite32be(ctrl, &ptu->timer[timer].ctrl);
+}
+
+
+/**
+ * @brief clear enable flag in timer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+
+void gptimer_clear_enabled(struct gptimer_unit *ptu, uint32_t timer)
+{
+	uint32_t ctrl;
+
+	ctrl  = ioread32be(&ptu->timer[timer].ctrl);
+	ctrl &= ~LEON3_TIMER_EN;
+
+	iowrite32be(ctrl, &ptu->timer[timer].ctrl);
+}
+
+
+/**
+ * @brief set restart flag in timer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+void gptimer_set_restart(struct gptimer_unit *ptu, uint32_t timer)
+{
+	uint32_t ctrl;
+
+	ctrl  = ioread32be(&ptu->timer[timer].ctrl);
+	ctrl |= LEON3_TIMER_RS;
+
+	iowrite32be(ctrl, &ptu->timer[timer].ctrl);
+}
+
+
+/**
+ * @brief clear restart flag in timer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+
+void gptimer_clear_restart(struct gptimer_unit *ptu, uint32_t timer)
+{
+	uint32_t ctrl;
+
+	ctrl  = ioread32be(&ptu->timer[timer].ctrl);
+	ctrl &= ~LEON3_TIMER_RS;
+
+	iowrite32be(ctrl, &ptu->timer[timer].ctrl);
+}
+
+
+/**
+ * @brief set timer to chain to the preceeding timer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+
+void gptimer_set_chained(struct gptimer_unit *ptu, uint32_t timer)
+{
+	uint32_t ctrl;
+
+	ctrl  = ioread32be(&ptu->timer[timer].ctrl);
+	ctrl |= LEON3_TIMER_CH;
+
+	iowrite32be(ctrl, &ptu->timer[timer].ctrl);
+}
+
+
+/**
+ * @brief clear timer to chain to the preceeding timer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+
+void gptimer_clear_chained(struct gptimer_unit *ptu, uint32_t timer)
+{
+	uint32_t ctrl;
+
+	ctrl  = ioread32be(&ptu->timer[timer].ctrl);
+	ctrl &= ~LEON3_TIMER_CH;
+
+	iowrite32be(ctrl, &ptu->timer[timer].ctrl);
+}
+
+
+/**
+ * @brief get status of interrupt pending status
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+
+uint32_t gptimer_get_interrupt_pending_status(struct gptimer_unit *ptu,
+					      uint32_t timer)
+{
+	return ioread32be(&ptu->timer[timer].ctrl) & LEON3_TIMER_IP;
+}
+
+
+/**
+ * @brief clear status of interrupt pending status
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+
+void gptimer_clear_interrupt_pending_status(struct gptimer_unit *ptu,
+					    uint32_t timer)
+{
+	uint32_t ctrl;
+
+	ctrl  = ioread32be(&ptu->timer[timer].ctrl);
+	ctrl &= ~LEON3_TIMER_IP;
+
+	iowrite32be(ctrl, &ptu->timer[timer].ctrl);
+}
+
+
+/**
+ * @brief get number of implemented general purpose timers
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+
+uint32_t gptimer_get_num_implemented(struct gptimer_unit *ptu)
+{
+	return ioread32be(&ptu->config) & LEON3_CFG_TIMERS_MASK;
+}
+
+
+/**
+ * @brief get interrupt ID of first implemented timer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ */
+
+uint32_t gptimer_get_first_timer_irq_id(struct gptimer_unit *ptu)
+{
+	return (ioread32be(&ptu->config) & LEON3_CFG_IRQNUM_MASK) >>
+		LEON3_CFG_IRQNUM_SHIFT;
+}
+
+
+/**
+ * @brief set the value of a gptimer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ * @param value the timer counter value to set
+ */
+
+void gptimer_set_value(struct gptimer_unit *ptu, uint32_t timer, uint32_t value)
+{
+	iowrite32be(value, &ptu->timer[timer].value);
+}
+
+/**
+ * @brief get the value of a gptimer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ * @param value the timer counter value to set
+ */
+
+uint32_t gptimer_get_value(struct gptimer_unit *ptu, uint32_t timer)
+{
+	return ioread32be(&ptu->timer[timer].value);
+}
+
+
+/**
+ * @brief set the reload of a gptimer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ * @param reload the timer counter reload to set
+ */
+
+void gptimer_set_reload(struct gptimer_unit *ptu,
+			uint32_t timer,
+			uint32_t reload)
+{
+	iowrite32be(reload, &ptu->timer[timer].reload);
+}
+
+/**
+ * @brief get the reload of a gptimer
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ * @param reload the timer counter reload to set
+ */
+
+uint32_t gptimer_get_reload(struct gptimer_unit *ptu, uint32_t timer)
+{
+	return ioread32be(&ptu->timer[timer].reload);
+}
+
+
+/**
+ * @brief starts a gptimer; emits an irq but does not enable reload on underflow
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ * @param value the timer counter value to set
+ */
+
+void gptimer_start(struct gptimer_unit *ptu, uint32_t timer, uint32_t value)
+{
+	gptimer_set_value(ptu, timer, value);
+	gptimer_set_reload(ptu, timer, value);
+
+	gptimer_set_interrupt_enabled(ptu, timer);
+	gptimer_set_load(ptu, timer);
+	gptimer_set_enabled(ptu, timer);
+}
+
+
+/**
+ * @brief start a gptimer, emits an irq and enables reload on underflow
+ * @param ptu a struct gptimer_unit
+ * @param timer the selected timer
+ * @param value the timer counter value to set
+ */
+
+void gptimer_start_cyclical(struct gptimer_unit *ptu,
+			    uint32_t timer, uint32_t value)
+{
+	gptimer_set_value(ptu, timer, value);
+	gptimer_set_reload(ptu, timer, value);
+
+
+	gptimer_set_interrupt_enabled(ptu, timer);
+	gptimer_set_load(ptu, timer);
+	gptimer_set_restart(ptu, timer);
+	gptimer_set_enabled(ptu, timer);
+}
diff --git a/arch/sparc/drv/grtimer.c b/arch/sparc/lib/grtimer.c
similarity index 99%
rename from arch/sparc/drv/grtimer.c
rename to arch/sparc/lib/grtimer.c
index 84fbfef..9cc03c1 100644
--- a/arch/sparc/drv/grtimer.c
+++ b/arch/sparc/lib/grtimer.c
@@ -1,5 +1,5 @@
 /**
- * @file   arch/sparc/drv/grtimer.c
+ * @file   arch/sparc/lib/grtimer.c
  * @ingroup time
  * @author Armin Luntzer (armin.luntzer@univie.ac.at),
  * @date   July, 2016
diff --git a/arch/sparc/drv/grtimer_longcount.c b/arch/sparc/lib/grtimer_longcount.c
similarity index 98%
rename from arch/sparc/drv/grtimer_longcount.c
rename to arch/sparc/lib/grtimer_longcount.c
index fc01c73..a336b9c 100644
--- a/arch/sparc/drv/grtimer_longcount.c
+++ b/arch/sparc/lib/grtimer_longcount.c
@@ -1,6 +1,6 @@
 /**
- * @file   leon3_grtimer_longcount.c
- * @ingroup timing
+ * @file   arch/sparc/lib/grtimer_longcount.c
+ * @ingroup time
  * @author Armin Luntzer (armin.luntzer@univie.ac.at),
  * @date   July, 2016
  *
-- 
GitLab