diff options
author | Anas Nashif <anas.nashif@intel.com> | 2015-11-21 20:58:15 -0500 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2016-02-05 20:24:48 -0500 |
commit | 9d6deb4e8c08925107d21140dbdfaba988fd37c8 (patch) | |
tree | fc73af86b6e810d198c645cf661b00dec1c744c5 /drivers/rtc | |
parent | d3d64ca4cf480d4773016acf6bc3dd588f9da5d0 (diff) |
rtc: add DesignWare RTC driver
Adding DW real time clock support. This driver is used by the Quark SE
and Quark D2000 SoCs.
Change-Id: Iba8ddee1b1b5fee298db95b63418e152774662a4
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 20 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 2 | ||||
-rw-r--r-- | drivers/rtc/rtc_dw.c | 156 | ||||
-rw-r--r-- | drivers/rtc/rtc_dw.h | 53 | ||||
-rw-r--r-- | drivers/rtc/rtc_static_irq_stubs.S | 32 |
5 files changed, 263 insertions, 0 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig new file mode 100644 index 000000000..65301a3d2 --- /dev/null +++ b/drivers/rtc/Kconfig @@ -0,0 +1,20 @@ +menuconfig RTC + bool "Real-Time Clock" + default n + help + Enable options for Real-Time Clock drivers. + +if RTC + +config RTC_DW + bool "Build Designware RTC Driver" + default n + help + Designware RTC driver. + +config RTC_IRQ_PRI + int "RTC Interrupt Priority" + default 2 + help + RTC Interrupt Priority. +endif # RTC diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile new file mode 100644 index 000000000..00be5cdeb --- /dev/null +++ b/drivers/rtc/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_RTC) += rtc_static_irq_stubs.o +obj-$(CONFIG_RTC_DW) += rtc_dw.o diff --git a/drivers/rtc/rtc_dw.c b/drivers/rtc/rtc_dw.c new file mode 100644 index 000000000..acf2db81f --- /dev/null +++ b/drivers/rtc/rtc_dw.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2015 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 <sys_io.h> +#include <stdio.h> +#include <rtc.h> +#include <init.h> +#include "board.h" + +#include "rtc_dw.h" + +#define CLK_RTC_DIV_DEF_MASK (0xFFFFFF83) +#define CCU_RTC_CLK_DIV_EN (2) + +static void (*rtc_dw_cb_fn)(void); + +static void rtc_dw_set_div(const enum clk_rtc_div div) +{ + /* set default division mask */ + uint32_t reg = + sys_read32(CLOCK_SYSTEM_CLOCK_CONTROL) & CLK_RTC_DIV_DEF_MASK; + reg |= (div << CCU_RTC_CLK_DIV_OFFSET); + sys_write32(reg, CLOCK_SYSTEM_CLOCK_CONTROL); + /* CLK Div en bit must be written from 0 -> 1 to apply new value */ + sys_set_bit(CLOCK_SYSTEM_CLOCK_CONTROL, CCU_RTC_CLK_DIV_EN); +} + +/** + * @brief Function to enable clock gating for the RTC + * @return N/A + */ +static void rtc_dw_enable(void) +{ + sys_set_bit(CLOCK_PERIPHERAL_BASE_ADDR, 11); + sys_set_bit(CLOCK_PERIPHERAL_BASE_ADDR, 1); +} + +/** + * @brief Function to disable clock gating for the RTC + * @return N/A + */ +static void rtc_dw_disable(void) +{ + sys_clear_bit(CLOCK_PERIPHERAL_BASE_ADDR, 11); +} + +/** + * @brief RTC alarm ISR + * + * calls a user defined callback + * + * @return N/A + */ +void rtc_dw_isr(void) +{ + /* Disable RTC interrupt */ + sys_clear_bit(RTC_BASE_ADDR + RTC_CCR, 0); + + if (rtc_dw_cb_fn) { + (*rtc_dw_cb_fn)(); + } + + /* clear interrupt */ + sys_read32(RTC_BASE_ADDR + RTC_EOI); +} +IRQ_CONNECT_STATIC(rtc, INT_RTC_IRQ, CONFIG_RTC_IRQ_PRI, rtc_dw_isr, 0); + +/** + * @brief Sets an RTC alarm + * @param alarm_val Alarm value + * @return 0 on success + */ +static int rtc_dw_set_alarm(const uint32_t alarm_val) +{ + sys_set_bit(RTC_BASE_ADDR + RTC_CCR, 0); + + sys_write32(alarm_val, RTC_BASE_ADDR + RTC_CMR); + + return DEV_OK; +} + +/** + * @brief Function to configure the RTC + * @param config pointer to a RTC configuration structure + * @return 0 on success + */ +static int rtc_dw_set_config(struct rtc_config *config) +{ + /* Set RTC divider - 32768 / 32.768 khz = 1 second. */ + rtc_dw_set_div(RTC_DIVIDER); + + /* set initial RTC value */ + sys_write32(config->init_val, RTC_BASE_ADDR + RTC_CLR); + + /* clear any pending interrupts */ + sys_read32(RTC_BASE_ADDR + RTC_EOI); + + rtc_dw_cb_fn = config->cb_fn; + if (config->alarm_enable) { + rtc_dw_set_alarm(config->alarm_val); + } else { + sys_clear_bit(RTC_BASE_ADDR + RTC_CCR, 0); + } + + return DEV_OK; +} + +/** + * @brief Read current RTC value + * @return current rtc value + */ +static uint32_t rtc_dw_read(void) +{ + return sys_read32(RTC_BASE_ADDR + RTC_CCVR); +} + +static struct rtc_driver_api funcs = { + .set_config = rtc_dw_set_config, + .read = rtc_dw_read, + .enable = rtc_dw_enable, + .disable = rtc_dw_disable, + .set_alarm = rtc_dw_set_alarm, +}; + +int rtc_dw_init(struct device *dev) +{ + IRQ_CONFIG(rtc, INT_RTC_IRQ, 0); + irq_enable(INT_RTC_IRQ); + SCSS_INTERRUPT->int_rtc_mask = INT_UNMASK_IA; + dev->driver_api = &funcs; + return DEV_OK; +} + +struct rtc_dw_dev_config rtc_dev = { + .base_address = RTC_BASE_ADDR, +}; + +#ifdef CONFIG_RTC_DW +DECLARE_DEVICE_INIT_CONFIG(rtc, RTC_DRV_NAME, &rtc_dw_init, &rtc_dev); + +nano_early_init(rtc, NULL); +#endif diff --git a/drivers/rtc/rtc_dw.h b/drivers/rtc/rtc_dw.h new file mode 100644 index 000000000..246f758d3 --- /dev/null +++ b/drivers/rtc/rtc_dw.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015 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. + */ + +#ifndef _RTC_DW_H_ +#define _RTC_DW_H_ + +#include <board.h> +#include <device.h> +#include <rtc.h> + +#define RTC_DRV_NAME "rtc" + +#define RTC_CCVR (0x0) +#define RTC_CMR (0x4) +#define RTC_CLR (0x8) +#define RTC_CCR (0xC) +#define RTC_STAT (0x10) +#define RTC_RSTAT (0x14) +#define RTC_EOI (0x18) +#define RTC_COMP_VERSION (0x1C) + +#define RTC_INTERRUPT_ENABLE (1 << 0) +#define RTC_INTERRUPT_MASK (1 << 1) +#define RTC_ENABLE (1 << 2) +#define RTC_WRAP_ENABLE (1 << 3) + +#define RTC_CLK_DIV_EN (1 << 2) +#define RTC_CLK_DIV_MASK (0xF << 3) +#define RTC_CLK_DIV_1_HZ (0xF << 3) +#define RTC_CLK_DIV_32768_HZ (0x0 << 3) +#define RTC_CLK_DIV_8192_HZ (0x2 << 3) +#define RTC_CLK_DIV_4096_HZ (0x3 << 3) + +struct rtc_dw_dev_config { + uint32_t base_address; +}; + +int rtc_dw_init(struct device *dev); + +#endif /* _RTC_DW_H_ */ diff --git a/drivers/rtc/rtc_static_irq_stubs.S b/drivers/rtc/rtc_static_irq_stubs.S new file mode 100644 index 000000000..c422eab11 --- /dev/null +++ b/drivers/rtc/rtc_static_irq_stubs.S @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015, Intel Corportation. + * + * 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. + */ + + +#define _ASMLANGUAGE + +#include <arch/x86/asm.h> +#include <drivers/ioapic.h> + +#if defined(CONFIG_RTC_DW) +#if defined(CONFIG_IOAPIC) + ioapic_mkstub rtc rtc_dw_isr 0 +#endif +#endif + +/* externs (internal APIs) */ + +GTEXT(_IntEnt) +GTEXT(_IntExit) |