diff options
Diffstat (limited to 'drivers/nxp/timer/nxp_timer.c')
-rw-r--r-- | drivers/nxp/timer/nxp_timer.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/drivers/nxp/timer/nxp_timer.c b/drivers/nxp/timer/nxp_timer.c new file mode 100644 index 0000000..e9f277f --- /dev/null +++ b/drivers/nxp/timer/nxp_timer.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <arch.h> +#include <arch_helpers.h> +#include <arm_gic.h> +#include <assert.h> +#include <gic_v2.h> +#include <mmio.h> +#include <nxp_timer.h> + +#define GPTCR_SWR (1 << 15) /* Software reset */ +#define GPTCR_24MEN (1 << 10) /* Enable 24MHz clock input */ +#define GPTCR_CLKSOURCE_OSC (5 << 6) /* Clock source OSC */ +#define GPTCR_CLKSOURCE_MASK (0x7 << 6) +#define GPTCR_ENMODE (1 << 1) /* Timer enable mode */ +#define GPTCR_TEN 1 /* Timer enable */ + +#define GPTPR_PRESCL_24M_SHIFT 12 +#define SYS_COUNTER_FREQ_IN_MHZ 3 +#define GPT_OSC_FREQ 3000 /* count in 1ms for 24MHz */ + +#define IRQ_OCMP2 (1 << 1) /* irq for output compare 2 */ + +#define GPTPR_TIMER_CTRL (gpt_base + 0x00) +#define GPTPR_TIMER_PRESCL (gpt_base + 0x04) +#define GPTPR_TIMER_STS (gpt_base + 0x08) +#define GPTPR_TIMER_IRQ (gpt_base + 0x0c) +#define GPTPR_TIMER_CMP1 (gpt_base + 0x10) +#define GPTPR_TIMER_CMP2 (gpt_base + 0x14) +#define GPTPR_TIMER_CMP3 (gpt_base + 0x18) +#define GPTPR_TIMER_CAPT1 (gpt_base + 0x1c) +#define GPTPR_TIMER_CAPT2 (gpt_base + 0x20) +#define GPTPR_TIMER_CNTR (gpt_base + 0x24) + +static uintptr_t gpt_base; + +int nxp_timer_program(unsigned long time_out_ms) +{ + unsigned int val; + + assert(gpt_base); + assert(time_out_ms); + + /* setup GP Timer */ + mmio_write_32(GPTPR_TIMER_CTRL, GPTCR_SWR); + mmio_write_32(GPTPR_TIMER_CTRL, 0); + mmio_write_32(GPTPR_TIMER_STS, 0x3f); /* clear all status */ + + /* get 3MHz from 24MHz */ + mmio_write_32(GPTPR_TIMER_PRESCL, (7 << GPTPR_PRESCL_24M_SHIFT)); + + + /* Calculate the load value */ + val = (GPT_OSC_FREQ * time_out_ms) * 1000; + mmio_write_32(GPTPR_TIMER_CMP2, val); + + /* + * Configure the timer in one shot mode via compare channel 2. + * timer counter width to 32 bits and un-mask the interrupt. + */ + mmio_write_32(GPTPR_TIMER_IRQ, IRQ_OCMP2); + + /* Enable the timer */ + val = mmio_read_32(GPTPR_TIMER_CTRL); + val &= ~GPTCR_CLKSOURCE_MASK; + val |= GPTCR_24MEN | GPTCR_CLKSOURCE_OSC | GPTCR_TEN | GPTCR_ENMODE; + mmio_write_32(GPTPR_TIMER_CTRL, val); + + return 0; +} + +static void nxp_timer_disable(void) +{ + unsigned int val; + + mmio_write_32(GPTPR_TIMER_IRQ, 0); + val = mmio_read_32(GPTPR_TIMER_CTRL); + val &= ~GPTCR_TEN; + mmio_write_32(GPTPR_TIMER_CTRL, val); + mmio_write_32(GPTPR_TIMER_STS, 0x3f); /* clear all status */ +} + +int nxp_timer_cancel(void) +{ + assert(gpt_base); + nxp_timer_disable(); + return 0; +} + +int nxp_timer_handler(void) +{ + assert(gpt_base); + nxp_timer_disable(); + return 0; +} + +int nxp_timer_init(uintptr_t base_addr) +{ + /* Check input parameters */ + assert(base_addr); + + /* Check for duplicate initialization */ + assert(gpt_base == 0); + + gpt_base = base_addr; + + return 0; +} |