altera_avalon_timer: new timer driver for Nios II
Tickless idle is not yet supported. We program the timer period to the desired system clock tick rate (sys_clock_hw_cycles_per_tick). This was renamed to the same name used in the Altera Embedded IP Peripherals Guide; used by other CPUs than Nios II. Change-Id: Ic4fca8c16b923295b77b63f98f45cd3483c5f560 Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
9b3b36bd7a
commit
133dab4a63
5 changed files with 162 additions and 50 deletions
|
@ -141,6 +141,7 @@ S: Supported
|
||||||
F: arch/nios2/
|
F: arch/nios2/
|
||||||
F: include/arch/nios2/
|
F: include/arch/nios2/
|
||||||
F: drivers/serial/uart_altera_jtag.c
|
F: drivers/serial/uart_altera_jtag.c
|
||||||
|
F: drivers/timer/altera_avalon_timer.c
|
||||||
|
|
||||||
NORDIC MDK
|
NORDIC MDK
|
||||||
M: Carles Cufi <carles.cufi@nordicsemi.no>
|
M: Carles Cufi <carles.cufi@nordicsemi.no>
|
||||||
|
|
|
@ -141,14 +141,15 @@ config CORTEX_M_SYSTICK
|
||||||
This module implements a kernel device driver for the Cortex-M processor
|
This module implements a kernel device driver for the Cortex-M processor
|
||||||
SYSTICK timer and provides the standard "system clock driver" interfaces.
|
SYSTICK timer and provides the standard "system clock driver" interfaces.
|
||||||
|
|
||||||
config NIOS2_AVALON_TIMER
|
config ALTERA_AVALON_TIMER
|
||||||
bool "Nios II Avalon Interval Timer"
|
bool "Altera Avalon Interval Timer"
|
||||||
default y
|
default y
|
||||||
depends on NIOS2
|
depends on NIOS2
|
||||||
help
|
help
|
||||||
This module implements a kernel device driver for the Nios II Avalon
|
This module implements a kernel device driver for the Altera Avalon
|
||||||
Interval Timer as described in the Embedded IP documentation. It
|
Interval Timer as described in the Embedded IP documentation, for use
|
||||||
provides the standard "system clock driver" interfaces.
|
with Nios II and possibly other Altera soft CPUs. It provides the
|
||||||
|
standard "system clock driver" interfaces.
|
||||||
|
|
||||||
config SYSTEM_CLOCK_DISABLE
|
config SYSTEM_CLOCK_DISABLE
|
||||||
bool "API to disable system clock"
|
bool "API to disable system clock"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
obj-$(CONFIG_HPET_TIMER) += hpet.o
|
obj-$(CONFIG_HPET_TIMER) += hpet.o
|
||||||
obj-$(CONFIG_LOAPIC_TIMER) += loapic_timer.o
|
obj-$(CONFIG_LOAPIC_TIMER) += loapic_timer.o
|
||||||
obj-$(CONFIG_ARCV2_TIMER) += arcv2_timer0.o
|
obj-$(CONFIG_ARCV2_TIMER) += arcv2_timer0.o
|
||||||
obj-$(CONFIG_NIOS2_AVALON_TIMER) += nios2_avalon_timer.o
|
obj-$(CONFIG_ALTERA_AVALON_TIMER) += altera_avalon_timer.o
|
||||||
|
|
||||||
_CORTEX_M_SYSTICK_AND_GDB_INFO_yy = y
|
_CORTEX_M_SYSTICK_AND_GDB_INFO_yy = y
|
||||||
obj-$(CONFIG_CORTEX_M_SYSTICK) += cortex_m_systick.o
|
obj-$(CONFIG_CORTEX_M_SYSTICK) += cortex_m_systick.o
|
||||||
|
|
154
drivers/timer/altera_avalon_timer.c
Normal file
154
drivers/timer/altera_avalon_timer.c
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Intel Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nanokernel.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Read the platform's timer hardware
|
||||||
|
*
|
||||||
|
* This routine returns the current time in terms of timer hardware clock
|
||||||
|
* cycles.
|
||||||
|
*
|
||||||
|
* @return up counter of elapsed clock cycles
|
||||||
|
*/
|
||||||
|
uint32_t sys_cycle_get_32(void)
|
||||||
|
{
|
||||||
|
return accumulated_cycle_count + get_snapshot();
|
||||||
|
}
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2016 Intel Corporation
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <nanokernel.h>
|
|
||||||
#include <arch/cpu.h>
|
|
||||||
#include <device.h>
|
|
||||||
|
|
||||||
int _sys_clock_driver_init(struct device *device)
|
|
||||||
{
|
|
||||||
ARG_UNUSED(device);
|
|
||||||
|
|
||||||
/* STUB */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @brief Read the platform's timer hardware
|
|
||||||
*
|
|
||||||
* This routine returns the current time in terms of timer hardware clock
|
|
||||||
* cycles.
|
|
||||||
*
|
|
||||||
* @return up counter of elapsed clock cycles
|
|
||||||
*/
|
|
||||||
uint32_t sys_cycle_get_32(void)
|
|
||||||
{
|
|
||||||
/* STUB */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue