qmsi: rtc: use built-in qmsi driver
Change-Id: If8e70c946f73abf03a695fecaeff30a9881f6e94 Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
987016b954
commit
80e9d63dec
8 changed files with 9 additions and 361 deletions
|
@ -35,52 +35,16 @@ config RTC_DRV_NAME
|
|||
RTC driver instance name
|
||||
|
||||
config RTC_QMSI
|
||||
depends on QMSI_DRIVERS
|
||||
bool "QMSI RTC Driver"
|
||||
depends on QMSI
|
||||
default n
|
||||
help
|
||||
Build QMSI RTC driver.
|
||||
|
||||
config RTC_QMSI_IRQ
|
||||
int "QMSI RTC Driver Interrupt number"
|
||||
depends on RTC_QMSI
|
||||
help
|
||||
RTC interrupt number
|
||||
|
||||
config RTC_QMSI_IRQ_PRI
|
||||
int "QMSI RTC Driver Interrupt priority"
|
||||
depends on RTC_QMSI
|
||||
help
|
||||
RTC interrupt priority.
|
||||
|
||||
config RTC_DW
|
||||
bool "Build Designware RTC Driver"
|
||||
default n
|
||||
help
|
||||
Designware RTC driver.
|
||||
|
||||
config RTC_DW_CLOCK_GATE
|
||||
bool "Enable clock gating"
|
||||
depends on RTC_DW
|
||||
select CLOCK_CONTROL
|
||||
default n
|
||||
help
|
||||
Enable clock gating on RTC DesignWare controller
|
||||
|
||||
config RTC_DW_CLOCK_GATE_DRV_NAME
|
||||
string "Clock gating driver name"
|
||||
depends on RTC_DW_CLOCK_GATE
|
||||
default ""
|
||||
|
||||
config RTC_DW_CLOCK_GATE_SUBSYS
|
||||
int "Clock controller's subsystem"
|
||||
depends on RTC_DW_CLOCK_GATE
|
||||
default 0
|
||||
|
||||
config RTC_DW_IRQ_PRI
|
||||
int "DesignWare RTC Driver Interrupt priority"
|
||||
depends on RTC_DW
|
||||
help
|
||||
RTC interrupt priority.
|
||||
|
||||
endif # RTC
|
||||
|
|
|
@ -1,4 +1 @@
|
|||
ccflags-$(CONFIG_RTC_QMSI) += -I$(CONFIG_QMSI_INSTALL_PATH)/include
|
||||
|
||||
obj-$(CONFIG_RTC_DW) += rtc_dw.o
|
||||
obj-$(CONFIG_RTC_QMSI) += rtc_qmsi.o
|
||||
|
|
|
@ -1,220 +0,0 @@
|
|||
/*
|
||||
* 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 <clock_control.h>
|
||||
#include "board.h"
|
||||
|
||||
#include "rtc_dw.h"
|
||||
|
||||
#define RTC_CLK_DIV_DEF_MASK (0xFFFFFF83)
|
||||
#define CCU_RTC_CLK_DIV_EN (2)
|
||||
|
||||
#ifdef RTC_DW_INT_MASK
|
||||
static inline void _rtc_dw_int_unmask(void)
|
||||
{
|
||||
sys_write32(sys_read32(RTC_DW_INT_MASK) & INT_UNMASK_IA,
|
||||
RTC_DW_INT_MASK);
|
||||
}
|
||||
#else
|
||||
#define _rtc_dw_int_unmask()
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RTC_DW_CLOCK_GATE
|
||||
static inline void _rtc_dw_clock_config(struct device *dev)
|
||||
{
|
||||
char *drv = CONFIG_RTC_DW_CLOCK_GATE_DRV_NAME;
|
||||
struct device *clk;
|
||||
|
||||
clk = device_get_binding(drv);
|
||||
if (clk) {
|
||||
struct rtc_dw_runtime *context = dev->driver_data;
|
||||
|
||||
context->clock = clk;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void _rtc_dw_clock_on(struct device *dev)
|
||||
{
|
||||
struct rtc_dw_dev_config *config = dev->config->config_info;
|
||||
struct rtc_dw_runtime *context = dev->driver_data;
|
||||
|
||||
clock_control_on(context->clock, config->clock_data);
|
||||
}
|
||||
|
||||
static inline void _rtc_dw_clock_off(struct device *dev)
|
||||
{
|
||||
struct rtc_dw_dev_config *config = dev->config->config_info;
|
||||
struct rtc_dw_runtime *context = dev->driver_data;
|
||||
|
||||
clock_control_off(context->clock, config->clock_data);
|
||||
}
|
||||
#else
|
||||
#define _rtc_dw_clock_config(...)
|
||||
#define _rtc_dw_clock_on(...)
|
||||
#define _rtc_dw_clock_off(...)
|
||||
#endif
|
||||
|
||||
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) & RTC_CLK_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(struct device *dev)
|
||||
{
|
||||
_rtc_dw_clock_on(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to disable clock gating for the RTC
|
||||
* @return N/A
|
||||
*/
|
||||
static void rtc_dw_disable(struct device *dev)
|
||||
{
|
||||
_rtc_dw_clock_off(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RTC alarm ISR
|
||||
*
|
||||
* calls a user defined callback
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
void rtc_dw_isr(void *arg)
|
||||
{
|
||||
struct device *dev = arg;
|
||||
struct rtc_dw_dev_config *rtc_dev = dev->config->config_info;
|
||||
struct rtc_dw_runtime *context = dev->driver_data;
|
||||
|
||||
/* Disable RTC interrupt */
|
||||
sys_clear_bit(rtc_dev->base_address + RTC_CCR, 0);
|
||||
|
||||
if (context->rtc_dw_cb_fn) {
|
||||
context->rtc_dw_cb_fn(dev);
|
||||
}
|
||||
|
||||
/* clear interrupt */
|
||||
sys_read32(rtc_dev->base_address + RTC_EOI);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets an RTC alarm
|
||||
* @param alarm_val Alarm value
|
||||
* @return 0 on success
|
||||
*/
|
||||
static int rtc_dw_set_alarm(struct device *dev, const uint32_t alarm_val)
|
||||
{
|
||||
struct rtc_dw_dev_config *rtc_dev = dev->config->config_info;
|
||||
|
||||
sys_set_bit(rtc_dev->base_address + RTC_CCR, 0);
|
||||
|
||||
sys_write32(alarm_val, rtc_dev->base_address + RTC_CMR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 device *dev, struct rtc_config *config)
|
||||
{
|
||||
struct rtc_dw_dev_config *rtc_dev = dev->config->config_info;
|
||||
struct rtc_dw_runtime *context = dev->driver_data;
|
||||
|
||||
/* 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_dev->base_address + RTC_CLR);
|
||||
|
||||
/* clear any pending interrupts */
|
||||
sys_read32(rtc_dev->base_address + RTC_EOI);
|
||||
|
||||
context->rtc_dw_cb_fn = config->cb_fn;
|
||||
if (config->alarm_enable) {
|
||||
rtc_dw_set_alarm(dev, config->alarm_val);
|
||||
} else {
|
||||
sys_clear_bit(rtc_dev->base_address + RTC_CCR, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read current RTC value
|
||||
* @return current rtc value
|
||||
*/
|
||||
static uint32_t rtc_dw_read(struct device *dev)
|
||||
{
|
||||
struct rtc_dw_dev_config *rtc_dev = dev->config->config_info;
|
||||
|
||||
return sys_read32(rtc_dev->base_address + RTC_CCVR);
|
||||
}
|
||||
|
||||
static struct rtc_driver_api 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);
|
||||
|
||||
struct rtc_dw_runtime rtc_runtime;
|
||||
|
||||
struct rtc_dw_dev_config rtc_dev = {
|
||||
.base_address = RTC_DW_BASE_ADDR,
|
||||
#ifdef CONFIG_RTC_DW_CLOCK_GATE
|
||||
.clock_data = UINT_TO_POINTER(CONFIG_RTC_DW_CLOCK_GATE_SUBSYS),
|
||||
#endif
|
||||
};
|
||||
|
||||
DEVICE_AND_API_INIT(rtc, CONFIG_RTC_DRV_NAME, &rtc_dw_init,
|
||||
&rtc_runtime, &rtc_dev,
|
||||
SECONDARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
|
||||
&api_funcs);
|
||||
|
||||
int rtc_dw_init(struct device *dev)
|
||||
{
|
||||
IRQ_CONNECT(RTC_DW_IRQ, CONFIG_RTC_DW_IRQ_PRI, rtc_dw_isr,
|
||||
DEVICE_GET(rtc), 0);
|
||||
irq_enable(RTC_DW_IRQ);
|
||||
|
||||
_rtc_dw_int_unmask();
|
||||
|
||||
_rtc_dw_clock_config(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* 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>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#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_runtime {
|
||||
void (*rtc_dw_cb_fn)(struct device *dev);
|
||||
#ifdef CONFIG_RTC_DW_CLOCK_GATE
|
||||
struct device *clock;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct rtc_dw_dev_config {
|
||||
uint32_t base_address;
|
||||
#ifdef CONFIG_RTC_DW_CLOCK_GATE
|
||||
void *clock_data;
|
||||
#endif
|
||||
};
|
||||
|
||||
int rtc_dw_init(struct device *dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _RTC_DW_H_ */
|
|
@ -81,11 +81,11 @@ static struct rtc_driver_api api = {
|
|||
|
||||
static int rtc_qmsi_init(struct device *dev)
|
||||
{
|
||||
IRQ_CONNECT(CONFIG_RTC_QMSI_IRQ, CONFIG_RTC_QMSI_IRQ_PRI, qm_rtc_isr_0, 0,
|
||||
IRQ_CONNECT(QM_IRQ_RTC_0, CONFIG_RTC_QMSI_IRQ_PRI, qm_rtc_isr_0, 0,
|
||||
IOAPIC_EDGE | IOAPIC_HIGH);
|
||||
|
||||
/* Unmask RTC interrupt */
|
||||
irq_enable(CONFIG_RTC_QMSI_IRQ);
|
||||
irq_enable(QM_IRQ_RTC_0);
|
||||
|
||||
/* Route RTC interrupt to Lakemont */
|
||||
QM_SCSS_INT->int_rtc_mask &= ~BIT(0);
|
||||
|
@ -94,8 +94,7 @@ static int rtc_qmsi_init(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DEVICE_INIT(rtc, CONFIG_RTC_DRV_NAME, &rtc_qmsi_init,
|
||||
NULL, NULL,
|
||||
DEVICE_INIT(rtc, CONFIG_RTC_DRV_NAME, &rtc_qmsi_init, NULL, NULL,
|
||||
SECONDARY, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
|
||||
|
||||
static struct device *rtc_qmsi_dev = DEVICE_GET(rtc);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue