[PATCH 5/8] generic_or1k BSP clock driver correction
Hesham Almatary
heshamelmatary at gmail.com
Sat Feb 27 18:57:52 UTC 2016
On Sat, Feb 20, 2016 at 11:01 PM, <jakob.viketoft at gmail.com> wrote:
> From: Jakob Viketoft <jakob.viketoft at aacmicrotec.com>
>
> - Improve the clock driver to use RTEMS default tick period
> or the on the one supplied by the application
> - Avoid rewriting the timer settings, since all we need is to clear the interrupt
> - Remove any mention of or1ksim in favour of generic_or1k
>
> Close #2600
> ---
> .../lib/libbsp/or1k/generic_or1k/clock/clockdrv.c | 109 ++++++++++-----------
> 1 file changed, 51 insertions(+), 58 deletions(-)
>
> diff --git a/c/src/lib/libbsp/or1k/generic_or1k/clock/clockdrv.c b/c/src/lib/libbsp/or1k/generic_or1k/clock/clockdrv.c
> index e01d2e5..60eec98 100644
> --- a/c/src/lib/libbsp/or1k/generic_or1k/clock/clockdrv.c
> +++ b/c/src/lib/libbsp/or1k/generic_or1k/clock/clockdrv.c
> @@ -3,13 +3,15 @@
> *
> * @ingroup bsp_clock
> *
> - * @brief or1k clock support.
> + * @brief generic_or1k clock support.
> */
>
> /*
> * generic_or1k Clock driver
> *
> * COPYRIGHT (c) 2014-2015 Hesham ALMatary <heshamelmatary at gmail.com>
> + * Copyright (c) 2014-2016 ÅAC Microtec AB <www.aacmicrotec.com>
> + * Jakob Viketoft <jakob.viketoft at aacmicrotec.com>
> *
> * The license and distribution terms for this file may be
> * found in the file LICENSE in this distribution or at
> @@ -25,35 +27,30 @@
> #include <rtems/timecounter.h>
>
> /* The number of clock cycles before generating a tick timer interrupt. */
> -#define TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT 0x09ED9
> -#define OR1K_CLOCK_CYCLE_TIME_NANOSECONDS 10
> +#define OR1K_CLOCK_CYCLE_TIME_NANOSECONDS (1000000000 / OR1K_BSP_CLOCK_FREQ)
clockdrv.c:30:61: error: 'OR1K_BSP_CLOCK_FREQ' undeclared (first use
in this function)
>
> -static struct timecounter or1ksim_tc;
> -
> -/* CPU counter */
> +static struct timecounter generic_or1k_tc;
> static CPU_Counter_ticks cpu_counter_ticks;
> +static uint32_t timer_counts_per_clock_tick;
>
> -/* This prototype is added here to Avoid warnings */
> +/* These prototypes are added here to avoid warnings */
> void Clock_isr(void *arg);
> +static uint32_t generic_or1k_get_timecount(struct timecounter *tc);
>
> static void generic_or1k_clock_at_tick(void)
> {
> - uint32_t TTMR;
> + uint32_t ttmr;
>
> - /* For TTMR register,
> - * The least significant 28 bits are the number of clock cycles
> - * before generating a tick timer interrupt. While the most
> - * significant 4 bits are used for mode configuration, tick timer
> - * interrupt enable and pending interrupts status.
> - */
> - TTMR = (CPU_OR1K_SPR_TTMR_MODE_RESTART | CPU_OR1K_SPR_TTMR_IE |
> - (TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT & CPU_OR1K_SPR_TTMR_TP_MASK)
> - ) & ~(CPU_OR1K_SPR_TTMR_IP);
> + /* Get TTMR value */
> + ttmr = _OR1K_mfspr(CPU_OR1K_SPR_TTMR);
>
> - _OR1K_mtspr(CPU_OR1K_SPR_TTMR, TTMR);
> - _OR1K_mtspr(CPU_OR1K_SPR_TTCR, 0);
> + /* Clear interrupt */
> + ttmr &= ~(CPU_OR1K_SPR_TTMR_IP);
>
> - cpu_counter_ticks += TTMR_NUM_OF_CLOCK_TICKS_INTERRUPT;
> + /* Write it back */
> + _OR1K_mtspr(CPU_OR1K_SPR_TTMR, ttmr);
> +
> + cpu_counter_ticks += timer_counts_per_clock_tick;
> }
>
> static void generic_or1k_clock_handler_install(
> @@ -61,35 +58,19 @@ static void generic_or1k_clock_handler_install(
> proc_ptr old_isr
> )
> {
> - rtems_status_code sc = RTEMS_SUCCESSFUL;
> old_isr = NULL;
> _CPU_ISR_install_vector(OR1K_EXCEPTION_TICK_TIMER,
> new_isr,
> old_isr);
> -
> - if (sc != RTEMS_SUCCESSFUL) {
> - rtems_fatal_error_occurred(0xdeadbeef);
> - }
> -}
> -
> -static uint32_t or1ksim_get_timecount(struct timecounter *tc)
> -{
> - uint32_t ticks_since_last_timer_interrupt;
> -
> - ticks_since_last_timer_interrupt = _OR1K_mfspr(CPU_OR1K_SPR_TTCR);
> -
> - return cpu_counter_ticks + ticks_since_last_timer_interrupt;
> -}
> -
> -CPU_Counter_ticks _CPU_Counter_read(void)
> -{
> - return or1ksim_get_timecount(NULL);
> }
>
> static void generic_or1k_clock_initialize(void)
> {
> - uint64_t frequency = (1000000000 / OR1K_CLOCK_CYCLE_TIME_NANOSECONDS);
> - uint32_t TTMR;
> + uint32_t ttmr;
> +
> + /* Calculate timer value for given time per clock tick */
> + timer_counts_per_clock_tick = (1000 * rtems_configuration_get_microseconds_per_tick()) /
> + OR1K_CLOCK_CYCLE_TIME_NANOSECONDS;
>
> /* For TTMR register,
> * The least significant 28 bits are the number of clock cycles
> @@ -97,40 +78,52 @@ static void generic_or1k_clock_initialize(void)
> * significant 4 bits are used for mode configuration, tick timer
> * interrupt enable and pending interrupts status.
> */
> + ttmr = (CPU_OR1K_SPR_TTMR_MODE_RESTART | CPU_OR1K_SPR_TTMR_IE |
> + (timer_counts_per_clock_tick & CPU_OR1K_SPR_TTMR_TP_MASK)) &
> + ~(CPU_OR1K_SPR_TTMR_IP);
>
> - /* FIXME: Long interval should pass since initializing the tick timer
> - * registers fires exceptions dispite interrupts has not been enabled yet.
> - */
> - TTMR = (CPU_OR1K_SPR_TTMR_MODE_RESTART | CPU_OR1K_SPR_TTMR_IE |
> - (0xFFED9 & CPU_OR1K_SPR_TTMR_TP_MASK)
> - ) & ~(CPU_OR1K_SPR_TTMR_IP);
> -
> - _OR1K_mtspr(CPU_OR1K_SPR_TTMR, TTMR);
> + _OR1K_mtspr(CPU_OR1K_SPR_TTMR, ttmr);
> _OR1K_mtspr(CPU_OR1K_SPR_TTCR, 0);
>
> + /* Initialize CPU Counter */
> + cpu_counter_ticks = 0;
> +
> /* Initialize timecounter */
> - or1ksim_tc.tc_get_timecount = or1ksim_get_timecount;
> - or1ksim_tc.tc_counter_mask = 0xffffffff;
> - or1ksim_tc.tc_frequency = frequency;
> - or1ksim_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
> - rtems_timecounter_install(&or1ksim_tc);
> + generic_or1k_tc.tc_get_timecount = generic_or1k_get_timecount;
> + generic_or1k_tc.tc_counter_mask = 0xffffffff;
> + generic_or1k_tc.tc_frequency = OR1K_BSP_CLOCK_FREQ;
> + generic_or1k_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
> + rtems_timecounter_install(&generic_or1k_tc);
> }
>
> static void generic_or1k_clock_cleanup(void)
> {
> - uint32_t sr;
> + uint32_t sr;
>
> sr = _OR1K_mfspr(CPU_OR1K_SPR_SR);
>
> /* Disable tick timer exceptions */
> - _OR1K_mtspr(CPU_OR1K_SPR_SR, (sr & ~CPU_OR1K_SPR_SR_IEE)
> - & ~CPU_OR1K_SPR_SR_TEE);
> + _OR1K_mtspr(CPU_OR1K_SPR_SR, sr & ~CPU_OR1K_SPR_SR_TEE);
>
> /* Invalidate tick timer config registers */
> _OR1K_mtspr(CPU_OR1K_SPR_TTCR, 0);
> _OR1K_mtspr(CPU_OR1K_SPR_TTMR, 0);
> }
>
> +static uint32_t generic_or1k_get_timecount(struct timecounter *tc)
> +{
> + uint32_t counts_since_last_timer_interrupt;
> +
> + counts_since_last_timer_interrupt = _OR1K_mfspr(CPU_OR1K_SPR_TTCR);
> +
> + return cpu_counter_ticks + counts_since_last_timer_interrupt;
> +}
> +
> +CPU_Counter_ticks _CPU_Counter_read(void)
> +{
> + return generic_or1k_get_timecount(NULL);
> +}
> +
> CPU_Counter_ticks _CPU_Counter_difference(
> CPU_Counter_ticks second,
> CPU_Counter_ticks first
> @@ -146,7 +139,7 @@ CPU_Counter_ticks _CPU_Counter_difference(
> #define Clock_driver_support_install_isr(isr, old_isr) \
> do { \
> old_isr = NULL; \
> - generic_or1k_clock_handler_install(isr, old_isr); \
> + generic_or1k_clock_handler_install(isr, old_isr); \
> } while (0)
>
> #define Clock_driver_support_shutdown_hardware() generic_or1k_clock_cleanup()
> --
> 2.1.4
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
--
Hesham
More information about the devel
mailing list