clock: add Quark SE clock control
Quark SE provides various clock controllers through its SCSS block. Peripheral, external, sensor, and others. This current drivers provides only the clock gating capability, for peripheral, external and sensor. But it could support divider and more other features once defined in the generic API. Note: such clock has _nothing_ to do with a Real Time Clock (RTC). An RTC provide clock timing like a watch would do. Here the clock controller is about circuit clocking. Change-Id: I1a365ae730dfc6be7686271f7fbb693e64a6ff6f Signed-off-by: Anas Nashif <anas.nashif@intel.com> Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
a9ed4ba9f5
commit
714dd9786b
7 changed files with 376 additions and 0 deletions
|
@ -57,4 +57,6 @@ source "drivers/rtc/Kconfig"
|
|||
|
||||
source "drivers/watchdog/Kconfig"
|
||||
|
||||
source "drivers/clock_control/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -20,3 +20,4 @@ obj-$(CONFIG_ADC) += adc/
|
|||
obj-$(CONFIG_ETHERNET) += ethernet/
|
||||
obj-$(CONFIG_WATCHDOG) += watchdog/
|
||||
obj-$(CONFIG_RTC) += rtc/
|
||||
obj-$(CONFIG_CLOCK_CONTROL) += clock_control/
|
||||
|
|
87
drivers/clock_control/Kconfig
Normal file
87
drivers/clock_control/Kconfig
Normal file
|
@ -0,0 +1,87 @@
|
|||
# Kconfig - Clock controller driver configuration options
|
||||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
#
|
||||
# Clock controller drivers
|
||||
#
|
||||
menuconfig CLOCK_CONTROL
|
||||
bool
|
||||
prompt "Hardware clock controller support"
|
||||
default n
|
||||
help
|
||||
Enable support for hardware clock controller. Such hardware can
|
||||
provide clock for other subsystem, and thus can be also used for
|
||||
power efficiency by controlling their clock. Note that this has
|
||||
nothing to do with RTC.
|
||||
|
||||
config CLOCK_CONTROL_DEBUG
|
||||
bool
|
||||
prompt "Hardware clock controller drivers debug output"
|
||||
depends on CLOCK_CONTROL
|
||||
default n
|
||||
|
||||
config CLOCK_CONTROL_QUARK_SE
|
||||
bool
|
||||
prompt "Quark SE Clock controller support"
|
||||
depends on CLOCK_CONTROL && PLATFORM_QUARK_SE_X86
|
||||
default n
|
||||
help
|
||||
Enable support for the Quark SE clock driver.
|
||||
|
||||
config CLOCK_CONTROL_QUARK_SE_PERIPHERAL
|
||||
bool
|
||||
prompt "Quark SE peripheral clock support"
|
||||
depends on CLOCK_CONTROL_QUARK_SE
|
||||
default n
|
||||
help
|
||||
Enable support for Quark SE peripheral clock which controls the
|
||||
clock of I2C, SPI, GPIO controllers and more.
|
||||
|
||||
config CLOCK_CONTROL_QUARK_SE_PERIPHERAL_DRV_NAME
|
||||
string
|
||||
prompt "Quark SE peripheral clock device name"
|
||||
depends on CLOCK_CONTROL_QUARK_SE_PERIPHERAL
|
||||
default "clk_peripheral"
|
||||
|
||||
config CLOCK_CONTROL_QUARK_SE_EXTERNAL
|
||||
bool
|
||||
prompt "Quark SE external clock support"
|
||||
depends on CLOCK_CONTROL_QUARK_SE
|
||||
default n
|
||||
help
|
||||
Enable support for Quark SE external sub-system clock.
|
||||
|
||||
config CLOCK_CONTROL_QUARK_SE_EXTERNAL_DRV_NAME
|
||||
string
|
||||
prompt "Quark SE external clock device name"
|
||||
depends on CLOCK_CONTROL_QUARK_SE_PERIPHERAL
|
||||
default "clk_external"
|
||||
|
||||
config CLOCK_CONTROL_QUARK_SE_SENSOR
|
||||
bool
|
||||
prompt "Quark SE sensor clock support"
|
||||
depends on CLOCK_CONTROL_QUARK_SE
|
||||
default n
|
||||
help
|
||||
Enable support for Quark SE sensor sub-system clock.
|
||||
|
||||
config CLOCK_CONTROL_QUARK_SE_SENSOR_DRV_NAME
|
||||
string
|
||||
prompt "Quark SE sensor clock device name"
|
||||
depends on CLOCK_CONTROL_QUARK_SE_PERIPHERAL
|
||||
default "clk_sensor"
|
1
drivers/clock_control/Makefile
Normal file
1
drivers/clock_control/Makefile
Normal file
|
@ -0,0 +1 @@
|
|||
obj-$(CONFIG_CLOCK_CONTROL_QUARK_SE) += quark_se_clock_control.o
|
138
drivers/clock_control/quark_se_clock_control.c
Normal file
138
drivers/clock_control/quark_se_clock_control.c
Normal file
|
@ -0,0 +1,138 @@
|
|||
/* quark_se_clock_control.c - Clock controller driver for Quark SE */
|
||||
|
||||
/*
|
||||
* 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 <arch/cpu.h>
|
||||
|
||||
#include <misc/__assert.h>
|
||||
#include <board.h>
|
||||
#include <device.h>
|
||||
#include <init.h>
|
||||
|
||||
#include <sys_io.h>
|
||||
|
||||
#include <clock_control.h>
|
||||
#include <clock_control/quark_se_clock_control.h>
|
||||
|
||||
#ifndef CONFIG_CLOCK_DEBUG
|
||||
#define DBG(...) {; }
|
||||
#else
|
||||
#if defined(CONFIG_STDOUT_CONSOLE)
|
||||
#include <stdio.h>
|
||||
#define DBG printf
|
||||
#else
|
||||
#include <misc/printk.h>
|
||||
#define DBG printk
|
||||
#endif /* CONFIG_STDOUT_CONSOLE */
|
||||
#endif /* CONFIG_CLOCK_DEBUG */
|
||||
|
||||
struct quark_se_clock_control_config {
|
||||
uint32_t base_address;
|
||||
};
|
||||
|
||||
static inline int quark_se_clock_control_on(struct device *dev,
|
||||
clock_control_subsys_t sub_system)
|
||||
{
|
||||
struct quark_se_clock_control_config *info = dev->config->config_info;
|
||||
uint32_t subsys = POINTER_TO_INT(sub_system);
|
||||
|
||||
if (sub_system == CLOCK_CONTROL_SUBSYS_ALL) {
|
||||
DBG("Enabling all clock gates on dev %p\n", dev);
|
||||
sys_write32(0xffffffff, info->base_address);
|
||||
|
||||
return DEV_OK;
|
||||
}
|
||||
|
||||
DBG("Enabling clock gate on dev %p subsystem %u\n", dev, subsys);
|
||||
|
||||
return sys_test_and_set_bit(info->base_address, subsys);
|
||||
}
|
||||
|
||||
static inline int quark_se_clock_control_off(struct device *dev,
|
||||
clock_control_subsys_t sub_system)
|
||||
{
|
||||
struct quark_se_clock_control_config *info = dev->config->config_info;
|
||||
uint32_t subsys = POINTER_TO_INT(sub_system);
|
||||
|
||||
if (sub_system == CLOCK_CONTROL_SUBSYS_ALL) {
|
||||
DBG("Disabling all clock gates on dev %p\n", dev);
|
||||
sys_write32(0x00000000, info->base_address);
|
||||
|
||||
return DEV_OK;
|
||||
}
|
||||
|
||||
DBG("clock gate on dev %p subsystem %u\n", dev, subsys);
|
||||
|
||||
return sys_test_and_clear_bit(info->base_address, subsys);
|
||||
}
|
||||
|
||||
static struct clock_control_driver_api quark_se_clock_control_api = {
|
||||
.on = quark_se_clock_control_on,
|
||||
.off = quark_se_clock_control_off
|
||||
};
|
||||
|
||||
int quark_se_clock_control_init(struct device *dev)
|
||||
{
|
||||
dev->driver_api = &quark_se_clock_control_api;
|
||||
|
||||
DBG("Quark Se clock controller driver initialized on device: %p\n",
|
||||
dev);
|
||||
return DEV_OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CLOCK_CONTROL_QUARK_SE_PERIPHERAL
|
||||
|
||||
struct quark_se_clock_control_config clock_quark_se_peripheral_config = {
|
||||
.base_address = CLOCK_PERIPHERAL_BASE_ADDR
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_INIT_CONFIG(clock_quark_se_peripheral,
|
||||
CONFIG_CLOCK_CONTROL_QUARK_SE_PERIPHERAL_DRV_NAME,
|
||||
&quark_se_clock_control_init,
|
||||
&clock_quark_se_peripheral_config);
|
||||
|
||||
pre_kernel_early_init(clock_quark_se_peripheral, NULL);
|
||||
|
||||
#endif /* CONFIG_CLOCK_CONTROL_QUARK_SE_PERIPHERAL */
|
||||
#ifdef CONFIG_CLOCK_CONTROL_QUARK_SE_EXTERNAL
|
||||
|
||||
struct quark_se_clock_control_config clock_quark_se_external_config = {
|
||||
.base_address = CLOCK_EXTERNAL_BASE_ADDR
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_INIT_CONFIG(clock_quark_se_external,
|
||||
CONFIG_CLOCK_CONTROL_QUARK_SE_EXTERNAL_DRV_NAME,
|
||||
&quark_se_clock_control_init,
|
||||
&clock_quark_se_external_config);
|
||||
|
||||
pre_kernel_early_init(clock_quark_se_external, NULL);
|
||||
|
||||
#endif /* CONFIG_CLOCK_CONTROL_QUARK_SE_EXTERNAL */
|
||||
#ifdef CONFIG_CLOCK_CONTROL_QUARK_SE_SENSOR
|
||||
|
||||
struct quark_se_clock_control_config clock_quark_se_sensor_config = {
|
||||
.base_address = CLOCK_SENSOR_BASE_ADDR
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_INIT_CONFIG(clock_quark_se_sensor,
|
||||
CONFIG_CLOCK_CONTROL_QUARK_SE_SENSOR_DRV_NAME,
|
||||
&quark_se_clock_control_init,
|
||||
&clock_quark_se_sensor_config);
|
||||
|
||||
pre_kernel_early_init(clock_quark_se_sensor, NULL);
|
||||
#endif /* CONFIG_CLOCK_CONTROL_QUARK_SE_SENSOR */
|
83
include/clock_control.h
Normal file
83
include/clock_control.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* clock_control.h - public clock controller driver API */
|
||||
|
||||
/*
|
||||
* 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 __CLOCK_CONTROL_H__
|
||||
#define __CLOCK_CONTROL_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <device.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Clock control API */
|
||||
|
||||
/* Used to select all subsystem of a clock controller */
|
||||
#define CLOCK_CONTROL_SUBSYS_ALL NULL
|
||||
|
||||
/**
|
||||
* clock_control_subsys_t is a type to identify a clock controller sub-system.
|
||||
* Such data pointed is opaque and relevant only to the clock controller
|
||||
* driver instance being used.
|
||||
*/
|
||||
typedef void *clock_control_subsys_t;
|
||||
|
||||
typedef int (*clock_control)(struct device *dev, clock_control_subsys_t sys);
|
||||
|
||||
struct clock_control_driver_api {
|
||||
clock_control on;
|
||||
clock_control off;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enable the clock of a sub-system controlled by the device
|
||||
* @param dev Pointer to the device structure for the clock controller driver
|
||||
* instance
|
||||
* @param sys A pointer to an opaque data representing the sub-system
|
||||
*/
|
||||
static inline int clock_control_on(struct device *dev,
|
||||
clock_control_subsys_t sys)
|
||||
{
|
||||
struct clock_control_driver_api *api;
|
||||
|
||||
api = (struct clock_control_driver_api *)dev->driver_api;
|
||||
return api->on(dev, sys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the clock of a sub-system controlled by the device
|
||||
* @param dev Pointer to the device structure for the clock controller driver
|
||||
* instance
|
||||
* @param sys A pointer to an opaque data representing the sub-system
|
||||
*/
|
||||
static inline int clock_control_off(struct device *dev,
|
||||
clock_control_subsys_t sys)
|
||||
{
|
||||
struct clock_control_driver_api *api;
|
||||
|
||||
api = (struct clock_control_driver_api *)dev->driver_api;
|
||||
return api->off(dev, sys);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CLOCK_CONTROL_H__ */
|
64
include/drivers/clock_control/quark_se_clock_control.h
Normal file
64
include/drivers/clock_control/quark_se_clock_control.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* quark_se_clock_control.h - Clock controller header for Quark SE */
|
||||
|
||||
/*
|
||||
* 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 __QUARK_SE_CLOCK_CONTROL_H__
|
||||
#define __QUARK_SE_CLOCK_CONTROL_H__
|
||||
|
||||
enum quark_se_peripheral_clocks {
|
||||
QUARK_SE_PERIPH_PCLK_EN = 0,
|
||||
QUARK_SE_CCU_PERIPH_PCLK_EN,
|
||||
QUARK_SE_CCU_I2C_M0_PCLK_EN,
|
||||
QUARK_SE_CCU_I2C_M1_PCLK_EN,
|
||||
QUARK_SE_CCU_SPI_S_PCLK_EN,
|
||||
QUARK_SE_CCU_SPI_M0_PCLK_EN,
|
||||
QUARK_SE_CCU_SPI_M1_PCLK_EN,
|
||||
QUARK_SE_CCU_GPIO_INTR_PCLK_EN,
|
||||
QUARK_SE_CCU_PERIPH_GPIO_DB_PCLK_EN,
|
||||
QUARK_SE_CCU_I2S_PCLK_EN,
|
||||
QUARK_SE_CCU_WDT_PCLK_EN_SW,
|
||||
QUARK_SE_CCU_RTC_PCLK_EN_SW,
|
||||
QUARK_SE_CCU_PWM_PCLK_EN_SW,
|
||||
QUARK_SE_CCU_GPIO_PCLK_EN_SW,
|
||||
QUARK_SE_CCU_SPI_M0_PCLK_EN_SW,
|
||||
QUARK_SE_CCU_SPI_M1_PCLK_EN_SW,
|
||||
QUARK_SE_CCU_SPI_PCLK_EN_SW,
|
||||
QUARK_SE_CCU_UARTA_PCLK_EN_SW,
|
||||
QUARK_SE_CCU_UARTB_PCLK_EN_SW,
|
||||
QUARK_SE_CCU_I2C_M0_PCLK_EN_SW,
|
||||
QUARK_SE_CCU_I2C_M1_PCLK_EN_SW,
|
||||
QUARK_SE_CCU_I2S_PCLK_EN_SW,
|
||||
};
|
||||
|
||||
enum quark_se_external_clocks {
|
||||
QUARK_SE_CCU_EXT_RTC_EN = 0,
|
||||
QUARK_SE_CCU_EXT_CLK_EN,
|
||||
QUARK_SE_CCU_EXT_CLK_DIV_EN,
|
||||
};
|
||||
|
||||
enum quark_se_sensor_clocks {
|
||||
QUARK_SE_CCU_SENSOR_CLK_EN = 0,
|
||||
QUARK_SE_CCU_SS_I2C_M0_CLK_EN,
|
||||
QUARK_SE_CCU_SS_I2C_M1_CLK_EN,
|
||||
QUARK_SE_CCU_SS_SPI_M0_CLK_EN,
|
||||
QUARK_SE_CCU_SS_SPI_M1_CLK_EN,
|
||||
QUARK_SE_CCU_SS_GPIO_INTR_CLK_EN,
|
||||
QUARK_SE_CCU_SS_GPIO_DB_CLK_EN,
|
||||
QUARK_SE_CCU_ADC_CLK_EN,
|
||||
};
|
||||
|
||||
#endif /* __QUARK_SE_CLOCK_CONTROL_H__ */
|
Loading…
Add table
Add a link
Reference in a new issue