diff --git a/arch/sparc/Kbuild b/arch/sparc/Kbuild index 133d36d17fca861eba256bfcbdedcc206ffd9cb9..082d329d32457042a5519ea71ba36ef3b1b579b6 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 316aaa172149f1c5fedfc277395b0d4b9859cda7..87c1fc4af37002ce9d035f0e49403509001a7a80 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 0000000000000000000000000000000000000000..5b220d0f2451f6cf5cc8f77671e19d7d30b58f0b --- /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 1a3edfce59882cfdd8a26819d62d8f8fa4be44ba..84d8e7d5cf7b591acf5e870556755aae9d84a766 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 5aaf9b61e9c94e095aaaac49f939543b4bc5667b..2b57684db1221a212221a36e8cdca768b3f582e7 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 0000000000000000000000000000000000000000..9ae67688ca355653da3267123e30ba1e1d671402 --- /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 84fbfeffe882f7a8d381cdc5ea315a2dce0a5eb8..9cc03c13fc9aa61203fb4f9cad70c1a8142c3baa 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 fc01c73f60bbec7b831da32712657b318cb9356c..a336b9c28355cdbcfa6da6cdb61f023e763e7925 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 *