counter: cmsdk: Add DualTimer as Counter
This patch adds Dualtimer to be used as a counter. Jira: ZEP-1300 Change-Id: Ic4a2d89ec7fc0c0c2a0bc7f6d32d97637049faaf Signed-off-by: Vincenzo Frascino <vincenzo.frascino@linaro.org>
This commit is contained in:
parent
b11242d11f
commit
b1e02a594a
5 changed files with 230 additions and 0 deletions
|
@ -18,4 +18,6 @@ source "drivers/counter/Kconfig.qmsi"
|
|||
|
||||
source "drivers/counter/Kconfig.tmr_cmsdk_apb"
|
||||
|
||||
source "drivers/counter/Kconfig.dtmr_cmsdk_apb"
|
||||
|
||||
endif # COUNTER
|
||||
|
|
39
drivers/counter/Kconfig.dtmr_cmsdk_apb
Normal file
39
drivers/counter/Kconfig.dtmr_cmsdk_apb
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Kconfig - counter configuration options
|
||||
#
|
||||
#
|
||||
# Copyright (c) 2016 Linaro Limited
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
if SOC_FAMILY_ARM
|
||||
|
||||
config COUNTER_DTMR_CMSDK_APB
|
||||
bool
|
||||
prompt "ARM CMSDK (Cortex-M System Design Kit) DTMR Counter driver"
|
||||
default n
|
||||
help
|
||||
The dualtimer (DTMR) present in the platform is used as a counter.
|
||||
This option enables the support for the counter.
|
||||
|
||||
if COUNTER_DTMR_CMSDK_APB
|
||||
|
||||
# ---------- Counter 0 ----------
|
||||
|
||||
config COUNTER_DTMR_CMSDK_APB_0
|
||||
bool
|
||||
prompt "Counter 0 driver"
|
||||
default n
|
||||
help
|
||||
Enable support for Counter 0.
|
||||
|
||||
config COUNTER_DTMR_CMSDK_APB_0_DEV_NAME
|
||||
string "Counter 0 Device Name"
|
||||
depends on COUNTER_DTMR_CMSDK_APB_0
|
||||
default "COUNTER_0"
|
||||
help
|
||||
Specify the device name for Counter 0 driver.
|
||||
|
||||
endif # COUNTER_DTMR_CMSDK_APB
|
||||
|
||||
endif # SOC_FAMILY_ARM
|
|
@ -2,3 +2,4 @@ obj-$(CONFIG_AON_COUNTER_QMSI) += counter_qmsi_aon.o
|
|||
obj-$(CONFIG_AON_TIMER_QMSI) += counter_qmsi_aonpt.o
|
||||
obj-$(CONFIG_COUNTER_TMR_CMSDK_APB) += counter_tmr_cmsdk_apb.o
|
||||
obj-$(CONFIG_TIMER_TMR_CMSDK_APB) += timer_tmr_cmsdk_apb.o
|
||||
obj-$(CONFIG_COUNTER_DTMR_CMSDK_APB) += counter_dtmr_cmsdk_apb.o
|
||||
|
|
120
drivers/counter/counter_dtmr_cmsdk_apb.c
Normal file
120
drivers/counter/counter_dtmr_cmsdk_apb.c
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Linaro Limited.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <counter.h>
|
||||
#include <device.h>
|
||||
#include <errno.h>
|
||||
#include <init.h>
|
||||
#include <soc.h>
|
||||
#include <clock_control/arm_clock_control.h>
|
||||
|
||||
#include "dualtimer_cmsdk_apb.h"
|
||||
|
||||
#define DUALTIMER_MAX_RELOAD 0xFFFFFFFF
|
||||
|
||||
struct counter_dtmr_cmsdk_apb_cfg {
|
||||
volatile struct dualtimer_cmsdk_apb *dtimer;
|
||||
/* Dualtimer Clock control in Active State */
|
||||
const struct arm_clock_control_t dtimer_cc_as;
|
||||
/* Dualtimer Clock control in Sleep State */
|
||||
const struct arm_clock_control_t dtimer_cc_ss;
|
||||
/* Dualtimer Clock control in Deep Sleep State */
|
||||
const struct arm_clock_control_t dtimer_cc_dss;
|
||||
};
|
||||
|
||||
static int counter_dtmr_cmsdk_apb_start(struct device *dev)
|
||||
{
|
||||
const struct counter_dtmr_cmsdk_apb_cfg * const cfg =
|
||||
dev->config->config_info;
|
||||
|
||||
/* Set the dualtimer to Max reload */
|
||||
cfg->dtimer->timer1load = DUALTIMER_MAX_RELOAD;
|
||||
|
||||
/* Enable the dualtimer in 32 bit mode */
|
||||
cfg->dtimer->timer1ctrl = (DUALTIMER_CTRL_EN | DUALTIMER_CTRL_SIZE_32);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int counter_dtmr_cmsdk_apb_stop(struct device *dev)
|
||||
{
|
||||
const struct counter_dtmr_cmsdk_apb_cfg * const cfg =
|
||||
dev->config->config_info;
|
||||
|
||||
/* Disable the dualtimer */
|
||||
cfg->dtimer->timer1ctrl = 0x0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t counter_dtmr_cmsdk_apb_read(struct device *dev)
|
||||
{
|
||||
const struct counter_dtmr_cmsdk_apb_cfg * const cfg =
|
||||
dev->config->config_info;
|
||||
|
||||
/* Return Counter Value */
|
||||
uint32_t value = 0;
|
||||
|
||||
value = DUALTIMER_MAX_RELOAD - cfg->dtimer->timer1value;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static int counter_dtmr_cmsdk_apb_set_alarm(struct device *dev,
|
||||
counter_callback_t callback,
|
||||
uint32_t count, void *user_data)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static const struct counter_driver_api counter_dtmr_cmsdk_apb_api = {
|
||||
.start = counter_dtmr_cmsdk_apb_start,
|
||||
.stop = counter_dtmr_cmsdk_apb_stop,
|
||||
.read = counter_dtmr_cmsdk_apb_read,
|
||||
.set_alarm = counter_dtmr_cmsdk_apb_set_alarm,
|
||||
};
|
||||
|
||||
static int counter_dtmr_cmsdk_apb_init(struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_CLOCK_CONTROL
|
||||
/* Enable clock for subsystem */
|
||||
struct device *clk =
|
||||
device_get_binding(CONFIG_ARM_CLOCK_CONTROL_DEV_NAME);
|
||||
|
||||
const struct counter_dtmr_cmsdk_apb_cfg * const cfg =
|
||||
dev->config->config_info;
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_BEETLE
|
||||
clock_control_on(clk, (clock_control_subsys_t *) &cfg->dtimer_cc_as);
|
||||
clock_control_on(clk, (clock_control_subsys_t *) &cfg->dtimer_cc_ss);
|
||||
clock_control_on(clk, (clock_control_subsys_t *) &cfg->dtimer_cc_dss);
|
||||
#endif /* CONFIG_SOC_SERIES_BEETLE */
|
||||
#else
|
||||
ARG_UNUSED(dev);
|
||||
#endif /* CONFIG_CLOCK_CONTROL */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* COUNTER 0 */
|
||||
#ifdef CONFIG_COUNTER_DTMR_CMSDK_APB_0
|
||||
static const struct counter_dtmr_cmsdk_apb_cfg counter_dtmr_cmsdk_apb_cfg_0 = {
|
||||
.dtimer = ((volatile struct dualtimer_cmsdk_apb *)CMSDK_APB_DTIMER),
|
||||
.dtimer_cc_as = {.bus = CMSDK_APB, .state = SOC_ACTIVE,
|
||||
.device = CMSDK_APB_DTIMER,},
|
||||
.dtimer_cc_ss = {.bus = CMSDK_APB, .state = SOC_SLEEP,
|
||||
.device = CMSDK_APB_DTIMER,},
|
||||
.dtimer_cc_dss = {.bus = CMSDK_APB, .state = SOC_DEEPSLEEP,
|
||||
.device = CMSDK_APB_DTIMER,},
|
||||
};
|
||||
|
||||
DEVICE_AND_API_INIT(counter_dtmr_cmsdk_apb_0,
|
||||
CONFIG_COUNTER_DTMR_CMSDK_APB_0_DEV_NAME,
|
||||
counter_dtmr_cmsdk_apb_init, NULL,
|
||||
&counter_dtmr_cmsdk_apb_cfg_0, POST_KERNEL,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
|
||||
&counter_dtmr_cmsdk_apb_api);
|
||||
#endif /* CONFIG_COUNTER_DTMR_CMSDK_APB_0 */
|
68
drivers/counter/dualtimer_cmsdk_apb.h
Normal file
68
drivers/counter/dualtimer_cmsdk_apb.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Linaro Limited.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _DRIVERS_DUALTIMER_CMSDK_AHB_
|
||||
#define _DRIVERS_DUALTIMER_CMSDK_AHB_
|
||||
|
||||
#include <counter.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct dualtimer_cmsdk_apb {
|
||||
/* Offset: 0x000 (R/W) Timer 1 Load */
|
||||
volatile uint32_t timer1load;
|
||||
/* Offset: 0x004 (R/ ) Timer 1 Counter Current Value */
|
||||
volatile uint32_t timer1value;
|
||||
/* Offset: 0x008 (R/W) Timer 1 Control */
|
||||
volatile uint32_t timer1ctrl;
|
||||
/* Offset: 0x00C ( /W) Timer 1 Interrupt Clear */
|
||||
volatile uint32_t timer1intclr;
|
||||
/* Offset: 0x010 (R/ ) Timer 1 Raw Interrupt Status */
|
||||
volatile uint32_t timer1ris;
|
||||
/* Offset: 0x014 (R/ ) Timer 1 Masked Interrupt Status */
|
||||
volatile uint32_t timer1mis;
|
||||
/* Offset: 0x018 (R/W) Background Load Register */
|
||||
volatile uint32_t timer1bgload;
|
||||
/* Reserved */
|
||||
volatile uint32_t reserved0;
|
||||
/* Offset: 0x020 (R/W) Timer 2 Load */
|
||||
volatile uint32_t timer2load;
|
||||
/* Offset: 0x024 (R/ ) Timer 2 Counter Current Value */
|
||||
volatile uint32_t timer2value;
|
||||
/* Offset: 0x028 (R/W) Timer 2 Control */
|
||||
volatile uint32_t timer2ctrl;
|
||||
/* Offset: 0x02C ( /W) Timer 2 Interrupt Clear */
|
||||
volatile uint32_t timer2intclr;
|
||||
/* Offset: 0x030 (R/ ) Timer 2 Raw Interrupt Status */
|
||||
volatile uint32_t timer2ris;
|
||||
/* Offset: 0x034 (R/ ) Timer 2 Masked Interrupt Status */
|
||||
volatile uint32_t timer2mis;
|
||||
/* Offset: 0x038 (R/W) Background Load Register */
|
||||
volatile uint32_t timer2bgload;
|
||||
/* Reserved */
|
||||
volatile uint32_t reserved1[945];
|
||||
/* Offset: 0xF00 (R/W) Integration Test Control Register */
|
||||
volatile uint32_t itcr;
|
||||
/* Offset: 0xF04 ( /W) Integration Test Output Set Register */
|
||||
volatile uint32_t itop;
|
||||
};
|
||||
|
||||
#define DUALTIMER_CTRL_EN (1 << 7)
|
||||
#define DUALTIMER_CTRL_MODE (1 << 6)
|
||||
#define DUALTIMER_CTRL_INTEN (1 << 5)
|
||||
#define DUALTIMER_CTRL_PRESCALE (3 << 2)
|
||||
#define DUALTIMER_CTRL_SIZE_32 (1 << 1)
|
||||
#define DUALTIMER_CTRL_ONESHOOT (1 << 0)
|
||||
#define DUALTIMER_INTCLR (1 << 0)
|
||||
#define DUALTIMER_RAWINTSTAT (1 << 0)
|
||||
#define DUALTIMER_MASKINTSTAT (1 << 0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _DRIVERS_DUALTIMER_CMSDK_AHB_ */
|
Loading…
Add table
Add a link
Reference in a new issue