zephyr/drivers/timer/altera_avalon_timer.c
David B. Kinder ac74d8b652 license: Replace Apache boilerplate with SPDX tag
Replace the existing Apache 2.0 boilerplate header with an SPDX tag
throughout the zephyr code tree. This patch was generated via a
script run over the master branch.

Also updated doc/porting/application.rst that had a dependency on
line numbers in a literal include.

Manually updated subsys/logging/sys_log.c that had a malformed
header in the original file.  Also cleanup several cases that already
had a SPDX tag and we either got a duplicate or missed updating.

Jira: ZEP-1457

Change-Id: I6131a1d4ee0e58f5b938300c2d2fc77d2e69572c
Signed-off-by: David B. Kinder <david.b.kinder@intel.com>
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2017-01-19 03:50:58 +00:00

136 lines
3.8 KiB
C

/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <arch/cpu.h>
#include <device.h>
#include <system_timer.h>
/* STATUS register */
#define ALTERA_AVALON_TIMER_STATUS_REG 0
#define ALTERA_AVALON_TIMER_STATUS_TO_MSK (0x1)
#define ALTERA_AVALON_TIMER_STATUS_TO_OFST (0)
#define ALTERA_AVALON_TIMER_STATUS_RUN_MSK (0x2)
#define ALTERA_AVALON_TIMER_STATUS_RUN_OFST (1)
/* CONTROL register */
#define ALTERA_AVALON_TIMER_CONTROL_REG 1
#define ALTERA_AVALON_TIMER_CONTROL_ITO_MSK (0x1)
#define ALTERA_AVALON_TIMER_CONTROL_ITO_OFST (0)
#define ALTERA_AVALON_TIMER_CONTROL_CONT_MSK (0x2)
#define ALTERA_AVALON_TIMER_CONTROL_CONT_OFST (1)
#define ALTERA_AVALON_TIMER_CONTROL_START_MSK (0x4)
#define ALTERA_AVALON_TIMER_CONTROL_START_OFST (2)
#define ALTERA_AVALON_TIMER_CONTROL_STOP_MSK (0x8)
#define ALTERA_AVALON_TIMER_CONTROL_STOP_OFST (3)
/* Period and SnapShot Register for COUNTER_SIZE = 32 */
/*----------------------------------------------------*/
/* PERIODL register */
#define ALTERA_AVALON_TIMER_PERIODL_REG 2
#define ALTERA_AVALON_TIMER_PERIODL_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_PERIODL_OFST (0)
/* PERIODH register */
#define ALTERA_AVALON_TIMER_PERIODH_REG 3
#define ALTERA_AVALON_TIMER_PERIODH_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_PERIODH_OFST (0)
/* SNAPL register */
#define ALTERA_AVALON_TIMER_SNAPL_REG 4
#define ALTERA_AVALON_TIMER_SNAPL_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_SNAPL_OFST (0)
/* SNAPH register */
#define ALTERA_AVALON_TIMER_SNAPH_REG 5
#define ALTERA_AVALON_TIMER_SNAPH_MSK (0xFFFF)
#define ALTERA_AVALON_TIMER_SNAPH_OFST (0)
static uint32_t accumulated_cycle_count;
static uint32_t get_snapshot(void)
{
#if TIMER_0_SNAPSHOT
uint32_t snap, s1, s2;
int key;
key = irq_lock();
/* Writing any data to one of the snapshot registers populates all
* of them with the value of the counter. The data written is ignored
*/
_nios2_reg_write((void *)TIMER_0_BASE, ALTERA_AVALON_TIMER_SNAPL_REG,
1);
s1 = _nios2_reg_read((void *)TIMER_0_BASE,
ALTERA_AVALON_TIMER_SNAPL_REG) &
ALTERA_AVALON_TIMER_SNAPL_MSK;
s2 = _nios2_reg_read((void *)TIMER_0_BASE,
ALTERA_AVALON_TIMER_SNAPH_REG) &
ALTERA_AVALON_TIMER_SNAPH_MSK;
irq_unlock(key);
snap = s1 | (s2 << 16);
return sys_clock_hw_cycles_per_tick - snap;
#else
return 0;
#endif
}
static void timer_irq_handler(void *unused)
{
ARG_UNUSED(unused);
/* Clear the interrupt */
_nios2_reg_write((void *)TIMER_0_BASE, ALTERA_AVALON_TIMER_STATUS_REG,
0);
accumulated_cycle_count += sys_clock_hw_cycles_per_tick;
_sys_clock_tick_announce();
}
#ifdef CONFIG_TICKLESS_IDLE
#error "Tickless idle not yet implemented for Avalon timer"
#endif
int _sys_clock_driver_init(struct device *device)
{
ARG_UNUSED(device);
#if TIMER_0_FIXED_PERIOD
#error "Can't set timer period!"
#else
_nios2_reg_write((void *)TIMER_0_BASE, ALTERA_AVALON_TIMER_PERIODL_REG,
sys_clock_hw_cycles_per_tick & 0xFFFF);
_nios2_reg_write((void *)TIMER_0_BASE, ALTERA_AVALON_TIMER_PERIODH_REG,
(sys_clock_hw_cycles_per_tick >> 16) & 0xFFFF);
#endif
IRQ_CONNECT(TIMER_0_IRQ, 0, timer_irq_handler, NULL, 0);
irq_enable(TIMER_0_IRQ);
/* Initial configuration: Generate interrupts, run continuously,
* start running
*/
_nios2_reg_write((void *)TIMER_0_BASE, ALTERA_AVALON_TIMER_CONTROL_REG,
ALTERA_AVALON_TIMER_CONTROL_ITO_MSK |
ALTERA_AVALON_TIMER_CONTROL_CONT_MSK |
ALTERA_AVALON_TIMER_CONTROL_START_MSK);
return 0;
}
uint32_t k_cycle_get_32(void)
{
return accumulated_cycle_count + get_snapshot();
}