summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2015-11-21 20:58:15 -0500
committerAnas Nashif <anas.nashif@intel.com>2016-02-05 20:24:48 -0500
commit9d6deb4e8c08925107d21140dbdfaba988fd37c8 (patch)
treefc73af86b6e810d198c645cf661b00dec1c744c5 /drivers
parentd3d64ca4cf480d4773016acf6bc3dd588f9da5d0 (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')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/rtc/Kconfig20
-rw-r--r--drivers/rtc/Makefile2
-rw-r--r--drivers/rtc/rtc_dw.c156
-rw-r--r--drivers/rtc/rtc_dw.h53
-rw-r--r--drivers/rtc/rtc_static_irq_stubs.S32
7 files changed, 266 insertions, 0 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 91dcf5a93..a5795d512 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -53,4 +53,6 @@ source "drivers/pinmux/Kconfig"
source "drivers/adc/Kconfig"
+source "drivers/rtc/Kconfig"
+
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index c6895d403..613a0a3af 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_I2C) += i2c/
obj-$(CONFIG_PWM) += pwm/
obj-$(CONFIG_ADC) += adc/
obj-$(CONFIG_ETHERNET) += ethernet/
+obj-$(CONFIG_RTC) += rtc/
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)