rtc: dw: Add support for optional clock gating
Clock gating is platform specific and not mandatory. Thus making in Kconfig based as well as generic. Change-Id: I01b7831536efd87cc66a95060fcf1faf4a340073 Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
d1d66a6200
commit
61c15ba1e1
6 changed files with 73 additions and 9 deletions
|
@ -136,7 +136,6 @@ struct scss_interrupt {
|
||||||
/* RTC */
|
/* RTC */
|
||||||
#define RTC_DW_INT_MASK (SCSS_INT_BASE + 0x78)
|
#define RTC_DW_INT_MASK (SCSS_INT_BASE + 0x78)
|
||||||
#define CCU_RTC_CLK_DIV_OFFSET 0x3
|
#define CCU_RTC_CLK_DIV_OFFSET 0x3
|
||||||
#define CCU_RTC_PCLK_EN_SW (1 << 11)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -179,6 +179,12 @@ endif
|
||||||
if RTC
|
if RTC
|
||||||
config RTC_DW
|
config RTC_DW
|
||||||
def_bool y
|
def_bool y
|
||||||
|
config RTC_DW_CLOCK_GATE
|
||||||
|
def_bool n
|
||||||
|
config RTC_DW_CLOCK_GATE_DRV_NAME
|
||||||
|
default CLOCK_CONTROL_QUARK_SE_PERIPHERAL_DRV_NAME
|
||||||
|
config RTC_DW_CLOCK_GATE_SUBSYS
|
||||||
|
default 11
|
||||||
config RTC_DW_BASE_ADDR
|
config RTC_DW_BASE_ADDR
|
||||||
default 0xB0000400
|
default 0xB0000400
|
||||||
config RTC_DW_IRQ
|
config RTC_DW_IRQ
|
||||||
|
|
|
@ -227,7 +227,6 @@ struct scss_interrupt {
|
||||||
/* RTC */
|
/* RTC */
|
||||||
#define RTC_DW_INT_MASK (SCSS_INT_BASE + 0x78)
|
#define RTC_DW_INT_MASK (SCSS_INT_BASE + 0x78)
|
||||||
#define CCU_RTC_CLK_DIV_OFFSET (3)
|
#define CCU_RTC_CLK_DIV_OFFSET (3)
|
||||||
#define CCU_RTC_PCLK_EN_SW (1 << 11)
|
|
||||||
|
|
||||||
/* Clock */
|
/* Clock */
|
||||||
#define CLOCK_PERIPHERAL_BASE_ADDR (SCSS_REGISTER_BASE + 0x18)
|
#define CLOCK_PERIPHERAL_BASE_ADDR (SCSS_REGISTER_BASE + 0x18)
|
||||||
|
|
|
@ -40,6 +40,24 @@ config RTC_DW_DRV_NAME
|
||||||
help
|
help
|
||||||
Designware RTC driver instance name
|
Designware RTC driver instance name
|
||||||
|
|
||||||
|
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_BASE_ADDR
|
config RTC_DW_BASE_ADDR
|
||||||
hex "Base address"
|
hex "Base address"
|
||||||
depends on RTC_DW
|
depends on RTC_DW
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <rtc.h>
|
#include <rtc.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
|
#include <clock_control.h>
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
|
|
||||||
#include "rtc_dw.h"
|
#include "rtc_dw.h"
|
||||||
|
@ -36,6 +37,41 @@ static inline void _rtc_dw_int_unmask(void)
|
||||||
#define _rtc_dw_int_unmask()
|
#define _rtc_dw_int_unmask()
|
||||||
#endif
|
#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)
|
static void rtc_dw_set_div(const enum clk_rtc_div div)
|
||||||
{
|
{
|
||||||
/* set default division mask */
|
/* set default division mask */
|
||||||
|
@ -53,10 +89,7 @@ static void rtc_dw_set_div(const enum clk_rtc_div div)
|
||||||
*/
|
*/
|
||||||
static void rtc_dw_enable(struct device *dev)
|
static void rtc_dw_enable(struct device *dev)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(dev);
|
_rtc_dw_clock_on(dev);
|
||||||
|
|
||||||
sys_set_bit(CLOCK_PERIPHERAL_BASE_ADDR, 11);
|
|
||||||
sys_set_bit(CLOCK_PERIPHERAL_BASE_ADDR, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,9 +98,7 @@ static void rtc_dw_enable(struct device *dev)
|
||||||
*/
|
*/
|
||||||
static void rtc_dw_disable(struct device *dev)
|
static void rtc_dw_disable(struct device *dev)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(dev);
|
_rtc_dw_clock_off(dev);
|
||||||
|
|
||||||
sys_clear_bit(CLOCK_PERIPHERAL_BASE_ADDR, 11);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -169,6 +200,8 @@ int rtc_dw_init(struct device *dev)
|
||||||
|
|
||||||
_rtc_dw_int_unmask();
|
_rtc_dw_int_unmask();
|
||||||
|
|
||||||
|
_rtc_dw_clock_config(dev);
|
||||||
|
|
||||||
dev->driver_api = &funcs;
|
dev->driver_api = &funcs;
|
||||||
|
|
||||||
return DEV_OK;
|
return DEV_OK;
|
||||||
|
@ -178,6 +211,9 @@ struct rtc_dw_runtime rtc_runtime;
|
||||||
|
|
||||||
struct rtc_dw_dev_config rtc_dev = {
|
struct rtc_dw_dev_config rtc_dev = {
|
||||||
.base_address = CONFIG_RTC_DW_BASE_ADDR,
|
.base_address = CONFIG_RTC_DW_BASE_ADDR,
|
||||||
|
#ifdef CONFIG_RTC_DW_CLOCK_GATE
|
||||||
|
.clock_data = UINT_TO_POINTER(CONFIG_RTC_DW_CLOCK_GATE_SUBSYS),
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_DEVICE_INIT_CONFIG(rtc, CONFIG_RTC_DW_DRV_NAME,
|
DECLARE_DEVICE_INIT_CONFIG(rtc, CONFIG_RTC_DW_DRV_NAME,
|
||||||
|
|
|
@ -44,10 +44,16 @@
|
||||||
|
|
||||||
struct rtc_dw_runtime {
|
struct rtc_dw_runtime {
|
||||||
void (*rtc_dw_cb_fn)(struct device *dev);
|
void (*rtc_dw_cb_fn)(struct device *dev);
|
||||||
|
#ifdef CONFIG_RTC_DW_CLOCK_GATE
|
||||||
|
struct device *clock;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rtc_dw_dev_config {
|
struct rtc_dw_dev_config {
|
||||||
uint32_t base_address;
|
uint32_t base_address;
|
||||||
|
#ifdef CONFIG_RTC_DW_CLOCK_GATE
|
||||||
|
void *clock_data;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
int rtc_dw_init(struct device *dev);
|
int rtc_dw_init(struct device *dev);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue