omap prcm changes via Paul Walmsley <paul@pwsan.com>:
Some miscellaneous OMAP hwmod changes for 3.8, along with a PRM change needed for one of the hwmod patches to function. Basic test logs for this branch on top of Tony's omap-for-v3.8/clock branch at commit558a0780b0
are here: http://www.pwsan.com/omap/testlogs/hwmod_devel_a_3.8/20121121161522/ However, omap-for-v3.8/clock at558a0780
does not include some fixes that are needed for a successful test. With several reverts, fixes, and workarounds applied, the following test logs were obtained: http://www.pwsan.com/omap/testlogs/TEST_hwmod_devel_a_3.8/20121121162719/ which indicate that the series tests cleanly. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJQs9J2AAoJEBvUPslcq6Vznz0QAM5Q8krs4fAZ35ekOnAAeh4a kWbkSq/VH74uPMbobUOeHVusJbfZBxm24CT/911wNXIHg/hku6WPhnQzStX2n/6w JKtHcQXeftgXecHBeyjDGdypcwknwTzIg78BECJi1FO+y/imaMjvxLDm74BXdBRF bLLmMLe2+Fnwz4IjwtOPz9mbje9NexMy+ppDyIVT36H+t9PQwDArOJMqLINWdioW e9LjUM4mr/5YZEOVu1tC30bJIcKq/m5yYS7dwifcSN67EsMUw90kQTKFtmNC2SzL DozIUHdsc990U65LhrH5EzoluT/tWPFl+ijkLmehfaVgSYIT5CmkDCgKUFNNY83r 7eVcPYvK8Nf2V8s0rMwy2mBy8j9p3Yug/kmOpRxdI90YCqxikJD5zdW+yQVX4qnt GXOyfw9BwK8g0Y7lEea1MN2s+y1E3n8EcaVyvQAW4N0wCkm3ELE6rm9HZoBXD3+d 4EovXn8DmTfvqiJ/M/FCqphyMMvp+NhO8Cg2vJUotEiCHdbIkaeXNI4AWg/sMlId aXUazd2i1WvynXvcSqJBbSKZQM+8GBPAuxqSQc8tP0JuOZo//sBYbXSUFClWksaw bvp+iJ6g/4/QqIG/B5EARSbkfCI1fTfTYObLe2Pd3cRdML3F0f/rCWRjPfl20BnQ weUVgyikcXT+aH2sfdIB =JSAM -----END PGP SIGNATURE----- Merge tag 'tags/omap-for-v3.8/devel-prcm-signed' into omap-for-v3.8/cleanup-headers-prepare-multiplatform-v3 omap prcm changes via Paul Walmsley <paul@pwsan.com>: Some miscellaneous OMAP hwmod changes for 3.8, along with a PRM change needed for one of the hwmod patches to function. Basic test logs for this branch on top of Tony's omap-for-v3.8/clock branch at commit558a0780b0
are here: http://www.pwsan.com/omap/testlogs/hwmod_devel_a_3.8/20121121161522/ However, omap-for-v3.8/clock at558a0780
does not include some fixes that are needed for a successful test. With several reverts, fixes, and workarounds applied, the following test logs were obtained: http://www.pwsan.com/omap/testlogs/TEST_hwmod_devel_a_3.8/20121121162719/ which indicate that the series tests cleanly. Conflicts: arch/arm/mach-omap2/cm33xx.c arch/arm/mach-omap2/io.c arch/arm/mach-omap2/prm_common.c
This commit is contained in:
commit
2589d05612
158 changed files with 16252 additions and 16649 deletions
|
@ -93,4 +93,6 @@ extern int ocpi_enable(void);
|
|||
static inline int ocpi_enable(void) { return 0; }
|
||||
#endif
|
||||
|
||||
extern u32 omap1_get_reset_sources(void);
|
||||
|
||||
#endif /* __ARCH_ARM_MACH_OMAP1_COMMON_H */
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include <linux/platform_data/omap-wd-timer.h>
|
||||
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include <mach/tc.h>
|
||||
|
@ -447,18 +449,31 @@ static struct resource wdt_resources[] = {
|
|||
};
|
||||
|
||||
static struct platform_device omap_wdt_device = {
|
||||
.name = "omap_wdt",
|
||||
.id = -1,
|
||||
.name = "omap_wdt",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(wdt_resources),
|
||||
.resource = wdt_resources,
|
||||
};
|
||||
|
||||
static int __init omap_init_wdt(void)
|
||||
{
|
||||
struct omap_wd_timer_platform_data pdata;
|
||||
int ret;
|
||||
|
||||
if (!cpu_is_omap16xx())
|
||||
return -ENODEV;
|
||||
|
||||
return platform_device_register(&omap_wdt_device);
|
||||
pdata.read_reset_sources = omap1_get_reset_sources;
|
||||
|
||||
ret = platform_device_register(&omap_wdt_device);
|
||||
if (!ret) {
|
||||
ret = platform_device_add_data(&omap_wdt_device, &pdata,
|
||||
sizeof(pdata));
|
||||
if (ret)
|
||||
platform_device_del(&omap_wdt_device);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
subsys_initcall(omap_init_wdt);
|
||||
#endif
|
||||
|
|
|
@ -4,12 +4,24 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/prcm.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#include "iomap.h"
|
||||
#include "common.h"
|
||||
|
||||
/* ARM_SYSST bit shifts related to SoC reset sources */
|
||||
#define ARM_SYSST_POR_SHIFT 5
|
||||
#define ARM_SYSST_EXT_RST_SHIFT 4
|
||||
#define ARM_SYSST_ARM_WDRST_SHIFT 2
|
||||
#define ARM_SYSST_GLOB_SWRST_SHIFT 1
|
||||
|
||||
/* Standardized reset source bits (across all OMAP SoCs) */
|
||||
#define OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT 0
|
||||
#define OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT 1
|
||||
#define OMAP_MPU_WD_RST_SRC_ID_SHIFT 3
|
||||
#define OMAP_EXTWARM_RST_SRC_ID_SHIFT 5
|
||||
|
||||
|
||||
void omap1_restart(char mode, const char *cmd)
|
||||
{
|
||||
/*
|
||||
|
@ -23,3 +35,28 @@ void omap1_restart(char mode, const char *cmd)
|
|||
|
||||
omap_writew(1, ARM_RSTCT1);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap1_get_reset_sources - return the source of the SoC's last reset
|
||||
*
|
||||
* Returns bits that represent the last reset source for the SoC. The
|
||||
* format is standardized across OMAPs for use by the OMAP watchdog.
|
||||
*/
|
||||
u32 omap1_get_reset_sources(void)
|
||||
{
|
||||
u32 ret = 0;
|
||||
u16 rs;
|
||||
|
||||
rs = __raw_readw(OMAP1_IO_ADDRESS(ARM_SYSST));
|
||||
|
||||
if (rs & (1 << ARM_SYSST_POR_SHIFT))
|
||||
ret |= 1 << OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT;
|
||||
if (rs & (1 << ARM_SYSST_EXT_RST_SHIFT))
|
||||
ret |= 1 << OMAP_EXTWARM_RST_SRC_ID_SHIFT;
|
||||
if (rs & (1 << ARM_SYSST_ARM_WDRST_SHIFT))
|
||||
ret |= 1 << OMAP_MPU_WD_RST_SRC_ID_SHIFT;
|
||||
if (rs & (1 << ARM_SYSST_GLOB_SWRST_SHIFT))
|
||||
ret |= 1 << OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ config ARCH_OMAP2
|
|||
select CPU_V6
|
||||
select MULTI_IRQ_HANDLER
|
||||
select SOC_HAS_OMAP2_SDRC
|
||||
select COMMON_CLK
|
||||
|
||||
config ARCH_OMAP3
|
||||
bool "TI OMAP3"
|
||||
|
@ -47,6 +48,7 @@ config ARCH_OMAP3
|
|||
select PM_OPP if PM
|
||||
select PM_RUNTIME if CPU_IDLE
|
||||
select SOC_HAS_OMAP2_SDRC
|
||||
select COMMON_CLK
|
||||
select USB_ARCH_HAS_EHCI if USB_SUPPORT
|
||||
|
||||
config ARCH_OMAP4
|
||||
|
@ -68,6 +70,7 @@ config ARCH_OMAP4
|
|||
select PM_OPP if PM
|
||||
select PM_RUNTIME if CPU_IDLE
|
||||
select USB_ARCH_HAS_EHCI if USB_SUPPORT
|
||||
select COMMON_CLK
|
||||
|
||||
config SOC_OMAP5
|
||||
bool "TI OMAP5"
|
||||
|
@ -77,6 +80,7 @@ config SOC_OMAP5
|
|||
select CPU_V7
|
||||
select HAVE_SMP
|
||||
select SOC_HAS_REALTIME_COUNTER
|
||||
select COMMON_CLK
|
||||
|
||||
comment "OMAP Core Type"
|
||||
depends on ARCH_OMAP2
|
||||
|
@ -111,6 +115,7 @@ config SOC_AM33XX
|
|||
select ARM_CPU_SUSPEND if PM
|
||||
select CPU_V7
|
||||
select MULTI_IRQ_HANDLER
|
||||
select COMMON_CLK
|
||||
|
||||
config OMAP_PACKAGE_ZAF
|
||||
bool
|
||||
|
|
|
@ -7,28 +7,34 @@ obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \
|
|||
common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
|
||||
omap_device.o sram.o
|
||||
|
||||
# INTCPS IP block support - XXX should be moved to drivers/
|
||||
obj-$(CONFIG_ARCH_OMAP2) += irq.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += irq.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += irq.o
|
||||
omap-2-3-common = irq.o
|
||||
hwmod-common = omap_hwmod.o \
|
||||
omap_hwmod_common_data.o
|
||||
clock-common = clock.o clock_common_data.o \
|
||||
clkt_dpll.o clkt_clksel.o
|
||||
secure-common = omap-smc.o omap-secure.o
|
||||
|
||||
# Secure monitor API support
|
||||
obj-$(CONFIG_ARCH_OMAP3) += omap-smc.o omap-secure.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += omap-smc.o omap-secure.o
|
||||
obj-$(CONFIG_SOC_OMAP5) += omap-smc.o omap-secure.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
|
||||
obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
|
||||
obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
|
||||
obj-$(CONFIG_SOC_AM33XX) += irq.o $(hwmod-common)
|
||||
obj-$(CONFIG_SOC_OMAP5) += prm44xx.o $(hwmod-common) $(secure-common)
|
||||
|
||||
ifneq ($(CONFIG_SND_OMAP_SOC_MCBSP),)
|
||||
obj-y += mcbsp.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
|
||||
obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
|
||||
obj-$(CONFIG_SOC_HAS_OMAP2_SDRC) += sdrc.o
|
||||
|
||||
# SMP support ONLY available for OMAP4
|
||||
|
||||
obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
|
||||
obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o
|
||||
obj-$(CONFIG_SOC_OMAP5) += omap4-common.o omap-wakeupgen.o
|
||||
omap-4-5-common = omap4-common.o omap-wakeupgen.o \
|
||||
sleep44xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-common)
|
||||
obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-common)
|
||||
|
||||
plus_sec := $(call as-instr,.arch_extension sec,+sec)
|
||||
AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
|
||||
|
@ -44,6 +50,11 @@ AFLAGS_sram242x.o :=-Wa,-march=armv6
|
|||
AFLAGS_sram243x.o :=-Wa,-march=armv6
|
||||
AFLAGS_sram34xx.o :=-Wa,-march=armv7-a
|
||||
|
||||
# Restart code (OMAP4/5 currently in omap4-common.c)
|
||||
obj-$(CONFIG_SOC_OMAP2420) += omap2-restart.o
|
||||
obj-$(CONFIG_SOC_OMAP2430) += omap2-restart.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += omap3-restart.o
|
||||
|
||||
# Pin multiplexing
|
||||
obj-$(CONFIG_SOC_OMAP2420) += mux2420.o
|
||||
obj-$(CONFIG_SOC_OMAP2430) += mux2430.o
|
||||
|
@ -53,7 +64,6 @@ obj-$(CONFIG_ARCH_OMAP4) += mux44xx.o
|
|||
# SMS/SDRC
|
||||
obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
|
||||
# obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o
|
||||
obj-$(CONFIG_SOC_HAS_OMAP2_SDRC) += sdrc.o
|
||||
|
||||
# OPP table initialization
|
||||
ifeq ($(CONFIG_PM_OPP),y)
|
||||
|
@ -66,15 +76,15 @@ endif
|
|||
obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
|
||||
|
||||
ifeq ($(CONFIG_PM),y)
|
||||
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o sleep24xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += sleep44xx.o
|
||||
obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o sleep44xx.o
|
||||
obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o
|
||||
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
|
||||
|
||||
obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o
|
||||
obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o
|
||||
obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o
|
||||
|
||||
AFLAGS_sleep24xx.o :=-Wa,-march=armv6
|
||||
AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec)
|
||||
|
@ -86,76 +96,82 @@ endif
|
|||
endif
|
||||
|
||||
ifeq ($(CONFIG_CPU_IDLE),y)
|
||||
obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += cpuidle34xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += cpuidle44xx.o
|
||||
endif
|
||||
|
||||
# PRCM
|
||||
obj-y += prcm.o prm_common.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += cm2xxx_3xxx.o prm2xxx_3xxx.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += cm2xxx_3xxx.o prm2xxx_3xxx.o
|
||||
obj-y += prm_common.o cm_common.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += prm2xxx_3xxx.o prm2xxx.o cm2xxx.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += prm2xxx_3xxx.o prm3xxx.o cm3xxx.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += vc3xxx_data.o vp3xxx_data.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += prm33xx.o cm33xx.o
|
||||
omap-prcm-4-5-common = cminst44xx.o cm44xx.o prm44xx.o \
|
||||
prcm_mpu44xx.o prminst44xx.o \
|
||||
vc44xx_data.o vp44xx_data.o \
|
||||
prm44xx.o
|
||||
vc44xx_data.o vp44xx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common)
|
||||
obj-$(CONFIG_SOC_OMAP5) += $(omap-prcm-4-5-common)
|
||||
|
||||
# OMAP voltage domains
|
||||
obj-y += voltage.o vc.o vp.o
|
||||
voltagedomain-common := voltage.o vc.o vp.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common)
|
||||
obj-$(CONFIG_ARCH_OMAP2) += voltagedomains2xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common)
|
||||
obj-$(CONFIG_ARCH_OMAP3) += voltagedomains3xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common)
|
||||
obj-$(CONFIG_ARCH_OMAP4) += voltagedomains44xx_data.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += voltagedomains33xx_data.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += $(voltagedomain-common)
|
||||
obj-$(CONFIG_SOC_AM33XX) += voltagedomains33xx_data.o
|
||||
obj-$(CONFIG_SOC_OMAP5) += $(voltagedomain-common)
|
||||
|
||||
# OMAP powerdomain framework
|
||||
obj-y += powerdomain.o powerdomain-common.o
|
||||
powerdomain-common += powerdomain.o powerdomain-common.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common)
|
||||
obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += powerdomain2xxx_3xxx.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_3xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += powerdomain2xxx_3xxx.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common)
|
||||
obj-$(CONFIG_ARCH_OMAP3) += powerdomains3xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += powerdomains2xxx_3xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += powerdomain44xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common)
|
||||
obj-$(CONFIG_ARCH_OMAP4) += powerdomains44xx_data.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += powerdomain33xx.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += $(powerdomain-common)
|
||||
obj-$(CONFIG_SOC_AM33XX) += powerdomains33xx_data.o
|
||||
obj-$(CONFIG_SOC_OMAP5) += powerdomain44xx.o
|
||||
obj-$(CONFIG_SOC_OMAP5) += $(powerdomain-common)
|
||||
|
||||
# PRCM clockdomain control
|
||||
obj-y += clockdomain.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += clockdomain2xxx_3xxx.o
|
||||
clockdomain-common += clockdomain.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common)
|
||||
obj-$(CONFIG_ARCH_OMAP2) += clockdomains2xxx_3xxx_data.o
|
||||
obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o
|
||||
obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += clockdomain2xxx_3xxx.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += $(clockdomain-common)
|
||||
obj-$(CONFIG_ARCH_OMAP3) += clockdomains2xxx_3xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += clockdomains3xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += clockdomain44xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common)
|
||||
obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += clockdomain33xx.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += $(clockdomain-common)
|
||||
obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o
|
||||
obj-$(CONFIG_SOC_OMAP5) += clockdomain44xx.o
|
||||
obj-$(CONFIG_SOC_OMAP5) += $(clockdomain-common)
|
||||
|
||||
# Clock framework
|
||||
obj-y += clock.o clock_common_data.o \
|
||||
clkt_dpll.o clkt_clksel.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += clock2xxx.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o clkt2xxx_sys.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_sys.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_apll.o clkt2xxx_osc.o
|
||||
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o
|
||||
obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o
|
||||
obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += clock3xxx.o
|
||||
obj-$(CONFIG_SOC_OMAP2420) += cclock2420_data.o
|
||||
obj-$(CONFIG_SOC_OMAP2430) += clock2430.o cclock2430_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o clkt34xx_dpll3m2.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o clkt_iclk.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o clock3xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += clock44xx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += clock3517.o clock36xx.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += dpll3xxx.o cclock3xxx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP3) += clkt_iclk.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) cclock44xx_data.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += dpll3xxx.o dpll44xx.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += dpll3xxx.o clock33xx_data.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += $(clock-common) dpll3xxx.o
|
||||
obj-$(CONFIG_SOC_AM33XX) += cclock33xx_data.o
|
||||
obj-$(CONFIG_SOC_OMAP5) += $(clock-common)
|
||||
obj-$(CONFIG_SOC_OMAP5) += dpll3xxx.o dpll44xx.o
|
||||
|
||||
# OMAP2 clock rate set data (old "OPP" data)
|
||||
|
@ -163,7 +179,6 @@ obj-$(CONFIG_SOC_OMAP2420) += opp2420_data.o
|
|||
obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o
|
||||
|
||||
# hwmod data
|
||||
obj-y += omap_hwmod_common_data.o
|
||||
obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_ipblock_data.o
|
||||
obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_3xxx_ipblock_data.o
|
||||
obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2xxx_interconnect_data.o
|
||||
|
@ -209,10 +224,10 @@ obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
|
|||
obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o
|
||||
obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
|
||||
obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o
|
||||
obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o
|
||||
obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o
|
||||
obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o
|
||||
obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o
|
||||
obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o
|
||||
obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o
|
||||
obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o
|
||||
obj-$(CONFIG_MACH_ENCORE) += board-omap3encore.o
|
||||
obj-$(CONFIG_MACH_OVERO) += board-overo.o
|
||||
obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o
|
||||
|
|
|
@ -21,5 +21,6 @@
|
|||
#define AM33XX_SCM_BASE 0x44E10000
|
||||
#define AM33XX_CTRL_BASE AM33XX_SCM_BASE
|
||||
#define AM33XX_PRCM_BASE 0x44E00000
|
||||
#define AM33XX_TAP_BASE (AM33XX_CTRL_BASE + 0x3FC)
|
||||
|
||||
#endif /* __ASM_ARCH_AM33XX_H */
|
||||
|
|
|
@ -285,5 +285,5 @@ MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
|
|||
.init_machine = omap_2430sdp_init,
|
||||
.init_late = omap2430_init_late,
|
||||
.timer = &omap2_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap2xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -597,5 +597,5 @@ MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
|
|||
.init_machine = omap_3430sdp_init,
|
||||
.init_late = omap3430_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -212,5 +212,5 @@ MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board")
|
|||
.init_machine = omap_sdp_init,
|
||||
.init_late = omap3630_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -881,5 +881,5 @@ MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
|
|||
.init_machine = omap_4430sdp_init,
|
||||
.init_late = omap4430_init_late,
|
||||
.timer = &omap4_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap44xx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -93,5 +93,5 @@ MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD")
|
|||
.init_machine = am3517_crane_init,
|
||||
.init_late = am35xx_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -393,5 +393,5 @@ MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
|
|||
.init_machine = am3517_evm_init,
|
||||
.init_late = am35xx_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -338,5 +338,5 @@ MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
|
|||
.init_machine = omap_apollon_init,
|
||||
.init_late = omap2420_init_late,
|
||||
.timer = &omap2_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap2xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -751,18 +751,18 @@ MACHINE_START(CM_T35, "Compulab CM-T35")
|
|||
.init_machine = cm_t35_init,
|
||||
.init_late = omap35xx_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
||||
MACHINE_START(CM_T3730, "Compulab CM-T3730")
|
||||
.atag_offset = 0x100,
|
||||
.reserve = omap_reserve,
|
||||
.map_io = omap3_map_io,
|
||||
.init_early = omap3630_init_early,
|
||||
.init_irq = omap3_init_irq,
|
||||
.atag_offset = 0x100,
|
||||
.reserve = omap_reserve,
|
||||
.map_io = omap3_map_io,
|
||||
.init_early = omap3630_init_early,
|
||||
.init_irq = omap3_init_irq,
|
||||
.handle_irq = omap3_intc_handle_irq,
|
||||
.init_machine = cm_t3730_init,
|
||||
.init_machine = cm_t3730_init,
|
||||
.init_late = omap3630_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -298,5 +298,5 @@ MACHINE_START(CM_T3517, "Compulab CM-T3517")
|
|||
.init_machine = cm_t3517_init,
|
||||
.init_late = am35xx_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -643,5 +643,5 @@ MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000")
|
|||
.init_machine = devkit8000_init,
|
||||
.init_late = omap35xx_init_late,
|
||||
.timer = &omap3_secure_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -57,7 +57,7 @@ DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
|
|||
.init_machine = omap_generic_init,
|
||||
.timer = &omap2_timer,
|
||||
.dt_compat = omap242x_boards_compat,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap2xxx_restart,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
|
@ -76,7 +76,7 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
|
|||
.init_machine = omap_generic_init,
|
||||
.timer = &omap2_timer,
|
||||
.dt_compat = omap243x_boards_compat,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap2xxx_restart,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
|
@ -95,7 +95,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
|
|||
.init_machine = omap_generic_init,
|
||||
.timer = &omap3_timer,
|
||||
.dt_compat = omap3_boards_compat,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
|
@ -134,7 +134,7 @@ DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")
|
|||
.init_late = omap4430_init_late,
|
||||
.timer = &omap4_timer,
|
||||
.dt_compat = omap4_boards_compat,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap44xx_restart,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
||||
|
@ -154,6 +154,6 @@ DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
|
|||
.init_machine = omap_generic_init,
|
||||
.timer = &omap5_timer,
|
||||
.dt_compat = omap5_boards_compat,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap44xx_restart,
|
||||
MACHINE_END
|
||||
#endif
|
||||
|
|
|
@ -386,5 +386,5 @@ MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
|
|||
.init_machine = omap_h4_init,
|
||||
.init_late = omap2420_init_late,
|
||||
.timer = &omap2_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap2xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -651,7 +651,7 @@ MACHINE_START(IGEP0020, "IGEP v2 board")
|
|||
.init_machine = igep_init,
|
||||
.init_late = omap35xx_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
||||
MACHINE_START(IGEP0030, "IGEP OMAP3 module")
|
||||
|
@ -664,5 +664,5 @@ MACHINE_START(IGEP0030, "IGEP OMAP3 module")
|
|||
.init_machine = igep_init,
|
||||
.init_late = omap35xx_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -436,5 +436,5 @@ MACHINE_START(OMAP_LDP, "OMAP LDP board")
|
|||
.init_machine = omap_ldp_init,
|
||||
.init_late = omap3430_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -690,7 +690,7 @@ MACHINE_START(NOKIA_N800, "Nokia N800")
|
|||
.init_machine = n8x0_init_machine,
|
||||
.init_late = omap2420_init_late,
|
||||
.timer = &omap2_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap2xxx_restart,
|
||||
MACHINE_END
|
||||
|
||||
MACHINE_START(NOKIA_N810, "Nokia N810")
|
||||
|
@ -703,7 +703,7 @@ MACHINE_START(NOKIA_N810, "Nokia N810")
|
|||
.init_machine = n8x0_init_machine,
|
||||
.init_late = omap2420_init_late,
|
||||
.timer = &omap2_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap2xxx_restart,
|
||||
MACHINE_END
|
||||
|
||||
MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
|
||||
|
@ -716,5 +716,5 @@ MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
|
|||
.init_machine = n8x0_init_machine,
|
||||
.init_late = omap2420_init_late,
|
||||
.timer = &omap2_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap2xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -545,5 +545,5 @@ MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
|
|||
.init_machine = omap3_beagle_init,
|
||||
.init_late = omap3_init_late,
|
||||
.timer = &omap3_secure_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -757,5 +757,5 @@ MACHINE_START(OMAP3EVM, "OMAP3 EVM")
|
|||
.init_machine = omap3_evm_init,
|
||||
.init_late = omap35xx_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -232,7 +232,7 @@ MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board")
|
|||
.init_machine = omap3logic_init,
|
||||
.init_late = omap35xx_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
||||
MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
|
||||
|
@ -245,5 +245,5 @@ MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
|
|||
.init_machine = omap3logic_init,
|
||||
.init_late = omap35xx_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -619,5 +619,5 @@ MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console")
|
|||
.init_machine = omap3pandora_init,
|
||||
.init_late = omap35xx_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -427,5 +427,5 @@ MACHINE_START(SBC3530, "OMAP3 STALKER")
|
|||
.init_machine = omap3_stalker_init,
|
||||
.init_late = omap35xx_init_late,
|
||||
.timer = &omap3_secure_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -387,5 +387,5 @@ MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
|
|||
.init_machine = omap3_touchbook_init,
|
||||
.init_late = omap3430_init_late,
|
||||
.timer = &omap3_secure_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -524,5 +524,5 @@ MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
|
|||
.init_machine = omap4_panda_init,
|
||||
.init_late = omap4430_init_late,
|
||||
.timer = &omap4_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap44xx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -552,5 +552,5 @@ MACHINE_START(OVERO, "Gumstix Overo")
|
|||
.init_machine = overo_init,
|
||||
.init_late = omap35xx_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -148,7 +148,7 @@ MACHINE_START(NOKIA_RM680, "Nokia RM-680 board")
|
|||
.init_machine = rm680_init,
|
||||
.init_late = omap3630_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
||||
MACHINE_START(NOKIA_RM696, "Nokia RM-696 board")
|
||||
|
@ -161,5 +161,5 @@ MACHINE_START(NOKIA_RM696, "Nokia RM-696 board")
|
|||
.init_machine = rm680_init,
|
||||
.init_late = omap3630_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -127,5 +127,5 @@ MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
|
|||
.init_machine = rx51_init,
|
||||
.init_late = omap3430_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -46,7 +46,7 @@ MACHINE_START(TI8168EVM, "ti8168evm")
|
|||
.timer = &omap3_timer,
|
||||
.init_machine = ti81xx_evm_init,
|
||||
.init_late = ti81xx_init_late,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap44xx_restart,
|
||||
MACHINE_END
|
||||
|
||||
MACHINE_START(TI8148EVM, "ti8148evm")
|
||||
|
@ -58,5 +58,5 @@ MACHINE_START(TI8148EVM, "ti8148evm")
|
|||
.timer = &omap3_timer,
|
||||
.init_machine = ti81xx_evm_init,
|
||||
.init_late = ti81xx_init_late,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap44xx_restart,
|
||||
MACHINE_END
|
||||
|
|
|
@ -138,7 +138,7 @@ MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
|
|||
.init_machine = omap_zoom_init,
|
||||
.init_late = omap3430_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
||||
MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
|
||||
|
@ -151,5 +151,5 @@ MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
|
|||
.init_machine = omap_zoom_init,
|
||||
.init_late = omap3630_init_late,
|
||||
.timer = &omap3_timer,
|
||||
.restart = omap_prcm_restart,
|
||||
.restart = omap3xxx_restart,
|
||||
MACHINE_END
|
||||
|
|
1950
arch/arm/mach-omap2/cclock2420_data.c
Normal file
1950
arch/arm/mach-omap2/cclock2420_data.c
Normal file
File diff suppressed because it is too large
Load diff
2065
arch/arm/mach-omap2/cclock2430_data.c
Normal file
2065
arch/arm/mach-omap2/cclock2430_data.c
Normal file
File diff suppressed because it is too large
Load diff
961
arch/arm/mach-omap2/cclock33xx_data.c
Normal file
961
arch/arm/mach-omap2/cclock33xx_data.c
Normal file
|
@ -0,0 +1,961 @@
|
|||
/*
|
||||
* AM33XX Clock data
|
||||
*
|
||||
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Vaibhav Hiremath <hvaibhav@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation version 2.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/clk-private.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "am33xx.h"
|
||||
#include "soc.h"
|
||||
#include "iomap.h"
|
||||
#include "clock.h"
|
||||
#include "control.h"
|
||||
#include "cm.h"
|
||||
#include "cm33xx.h"
|
||||
#include "cm-regbits-33xx.h"
|
||||
#include "prm.h"
|
||||
|
||||
/* Modulemode control */
|
||||
#define AM33XX_MODULEMODE_HWCTRL_SHIFT 0
|
||||
#define AM33XX_MODULEMODE_SWCTRL_SHIFT 1
|
||||
|
||||
/*LIST_HEAD(clocks);*/
|
||||
|
||||
/* Root clocks */
|
||||
|
||||
/* RTC 32k */
|
||||
DEFINE_CLK_FIXED_RATE(clk_32768_ck, CLK_IS_ROOT, 32768, 0x0);
|
||||
|
||||
/* On-Chip 32KHz RC OSC */
|
||||
DEFINE_CLK_FIXED_RATE(clk_rc32k_ck, CLK_IS_ROOT, 32000, 0x0);
|
||||
|
||||
/* Crystal input clks */
|
||||
DEFINE_CLK_FIXED_RATE(virt_19200000_ck, CLK_IS_ROOT, 19200000, 0x0);
|
||||
|
||||
DEFINE_CLK_FIXED_RATE(virt_24000000_ck, CLK_IS_ROOT, 24000000, 0x0);
|
||||
|
||||
DEFINE_CLK_FIXED_RATE(virt_25000000_ck, CLK_IS_ROOT, 25000000, 0x0);
|
||||
|
||||
DEFINE_CLK_FIXED_RATE(virt_26000000_ck, CLK_IS_ROOT, 26000000, 0x0);
|
||||
|
||||
/* Oscillator clock */
|
||||
/* 19.2, 24, 25 or 26 MHz */
|
||||
static const char *sys_clkin_ck_parents[] = {
|
||||
"virt_19200000_ck", "virt_24000000_ck", "virt_25000000_ck",
|
||||
"virt_26000000_ck",
|
||||
};
|
||||
|
||||
/*
|
||||
* sys_clk in: input to the dpll and also used as funtional clock for,
|
||||
* adc_tsc, smartreflex0-1, timer1-7, mcasp0-1, dcan0-1, cefuse
|
||||
*
|
||||
*/
|
||||
DEFINE_CLK_MUX(sys_clkin_ck, sys_clkin_ck_parents, NULL, 0x0,
|
||||
AM33XX_CTRL_REGADDR(AM33XX_CONTROL_STATUS),
|
||||
AM33XX_CONTROL_STATUS_SYSBOOT1_SHIFT,
|
||||
AM33XX_CONTROL_STATUS_SYSBOOT1_WIDTH,
|
||||
0, NULL);
|
||||
|
||||
/* External clock - 12 MHz */
|
||||
DEFINE_CLK_FIXED_RATE(tclkin_ck, CLK_IS_ROOT, 12000000, 0x0);
|
||||
|
||||
/* Module clocks and DPLL outputs */
|
||||
|
||||
/* DPLL_CORE */
|
||||
static struct dpll_data dpll_core_dd = {
|
||||
.mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_CORE,
|
||||
.clk_bypass = &sys_clkin_ck,
|
||||
.clk_ref = &sys_clkin_ck,
|
||||
.control_reg = AM33XX_CM_CLKMODE_DPLL_CORE,
|
||||
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
|
||||
.idlest_reg = AM33XX_CM_IDLEST_DPLL_CORE,
|
||||
.mult_mask = AM33XX_DPLL_MULT_MASK,
|
||||
.div1_mask = AM33XX_DPLL_DIV_MASK,
|
||||
.enable_mask = AM33XX_DPLL_EN_MASK,
|
||||
.idlest_mask = AM33XX_ST_DPLL_CLK_MASK,
|
||||
.max_multiplier = 2047,
|
||||
.max_divider = 128,
|
||||
.min_divider = 1,
|
||||
};
|
||||
|
||||
/* CLKDCOLDO output */
|
||||
static const char *dpll_core_ck_parents[] = {
|
||||
"sys_clkin_ck",
|
||||
};
|
||||
|
||||
static struct clk dpll_core_ck;
|
||||
|
||||
static const struct clk_ops dpll_core_ck_ops = {
|
||||
.recalc_rate = &omap3_dpll_recalc,
|
||||
.get_parent = &omap2_init_dpll_parent,
|
||||
};
|
||||
|
||||
static struct clk_hw_omap dpll_core_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &dpll_core_ck,
|
||||
},
|
||||
.dpll_data = &dpll_core_dd,
|
||||
.ops = &clkhwops_omap3_dpll,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(dpll_core_ck, dpll_core_ck_parents, dpll_core_ck_ops);
|
||||
|
||||
static const char *dpll_core_x2_ck_parents[] = {
|
||||
"dpll_core_ck",
|
||||
};
|
||||
|
||||
static struct clk dpll_core_x2_ck;
|
||||
|
||||
static const struct clk_ops dpll_x2_ck_ops = {
|
||||
.recalc_rate = &omap3_clkoutx2_recalc,
|
||||
};
|
||||
|
||||
static struct clk_hw_omap dpll_core_x2_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &dpll_core_x2_ck,
|
||||
},
|
||||
.flags = CLOCK_CLKOUTX2,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(dpll_core_x2_ck, dpll_core_x2_ck_parents, dpll_x2_ck_ops);
|
||||
|
||||
DEFINE_CLK_DIVIDER(dpll_core_m4_ck, "dpll_core_x2_ck", &dpll_core_x2_ck,
|
||||
0x0, AM33XX_CM_DIV_M4_DPLL_CORE,
|
||||
AM33XX_HSDIVIDER_CLKOUT1_DIV_SHIFT,
|
||||
AM33XX_HSDIVIDER_CLKOUT1_DIV_WIDTH, CLK_DIVIDER_ONE_BASED,
|
||||
NULL);
|
||||
|
||||
DEFINE_CLK_DIVIDER(dpll_core_m5_ck, "dpll_core_x2_ck", &dpll_core_x2_ck,
|
||||
0x0, AM33XX_CM_DIV_M5_DPLL_CORE,
|
||||
AM33XX_HSDIVIDER_CLKOUT2_DIV_SHIFT,
|
||||
AM33XX_HSDIVIDER_CLKOUT2_DIV_WIDTH,
|
||||
CLK_DIVIDER_ONE_BASED, NULL);
|
||||
|
||||
DEFINE_CLK_DIVIDER(dpll_core_m6_ck, "dpll_core_x2_ck", &dpll_core_x2_ck,
|
||||
0x0, AM33XX_CM_DIV_M6_DPLL_CORE,
|
||||
AM33XX_HSDIVIDER_CLKOUT3_DIV_SHIFT,
|
||||
AM33XX_HSDIVIDER_CLKOUT3_DIV_WIDTH,
|
||||
CLK_DIVIDER_ONE_BASED, NULL);
|
||||
|
||||
|
||||
/* DPLL_MPU */
|
||||
static struct dpll_data dpll_mpu_dd = {
|
||||
.mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_MPU,
|
||||
.clk_bypass = &sys_clkin_ck,
|
||||
.clk_ref = &sys_clkin_ck,
|
||||
.control_reg = AM33XX_CM_CLKMODE_DPLL_MPU,
|
||||
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
|
||||
.idlest_reg = AM33XX_CM_IDLEST_DPLL_MPU,
|
||||
.mult_mask = AM33XX_DPLL_MULT_MASK,
|
||||
.div1_mask = AM33XX_DPLL_DIV_MASK,
|
||||
.enable_mask = AM33XX_DPLL_EN_MASK,
|
||||
.idlest_mask = AM33XX_ST_DPLL_CLK_MASK,
|
||||
.max_multiplier = 2047,
|
||||
.max_divider = 128,
|
||||
.min_divider = 1,
|
||||
};
|
||||
|
||||
/* CLKOUT: fdpll/M2 */
|
||||
static struct clk dpll_mpu_ck;
|
||||
|
||||
static const struct clk_ops dpll_mpu_ck_ops = {
|
||||
.enable = &omap3_noncore_dpll_enable,
|
||||
.disable = &omap3_noncore_dpll_disable,
|
||||
.recalc_rate = &omap3_dpll_recalc,
|
||||
.round_rate = &omap2_dpll_round_rate,
|
||||
.set_rate = &omap3_noncore_dpll_set_rate,
|
||||
.get_parent = &omap2_init_dpll_parent,
|
||||
};
|
||||
|
||||
static struct clk_hw_omap dpll_mpu_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &dpll_mpu_ck,
|
||||
},
|
||||
.dpll_data = &dpll_mpu_dd,
|
||||
.ops = &clkhwops_omap3_dpll,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(dpll_mpu_ck, dpll_core_ck_parents, dpll_mpu_ck_ops);
|
||||
|
||||
/*
|
||||
* TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
|
||||
* and ALT_CLK1/2)
|
||||
*/
|
||||
DEFINE_CLK_DIVIDER(dpll_mpu_m2_ck, "dpll_mpu_ck", &dpll_mpu_ck,
|
||||
0x0, AM33XX_CM_DIV_M2_DPLL_MPU, AM33XX_DPLL_CLKOUT_DIV_SHIFT,
|
||||
AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
|
||||
|
||||
/* DPLL_DDR */
|
||||
static struct dpll_data dpll_ddr_dd = {
|
||||
.mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_DDR,
|
||||
.clk_bypass = &sys_clkin_ck,
|
||||
.clk_ref = &sys_clkin_ck,
|
||||
.control_reg = AM33XX_CM_CLKMODE_DPLL_DDR,
|
||||
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
|
||||
.idlest_reg = AM33XX_CM_IDLEST_DPLL_DDR,
|
||||
.mult_mask = AM33XX_DPLL_MULT_MASK,
|
||||
.div1_mask = AM33XX_DPLL_DIV_MASK,
|
||||
.enable_mask = AM33XX_DPLL_EN_MASK,
|
||||
.idlest_mask = AM33XX_ST_DPLL_CLK_MASK,
|
||||
.max_multiplier = 2047,
|
||||
.max_divider = 128,
|
||||
.min_divider = 1,
|
||||
};
|
||||
|
||||
/* CLKOUT: fdpll/M2 */
|
||||
static struct clk dpll_ddr_ck;
|
||||
|
||||
static const struct clk_ops dpll_ddr_ck_ops = {
|
||||
.recalc_rate = &omap3_dpll_recalc,
|
||||
.get_parent = &omap2_init_dpll_parent,
|
||||
.round_rate = &omap2_dpll_round_rate,
|
||||
.set_rate = &omap3_noncore_dpll_set_rate,
|
||||
};
|
||||
|
||||
static struct clk_hw_omap dpll_ddr_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &dpll_ddr_ck,
|
||||
},
|
||||
.dpll_data = &dpll_ddr_dd,
|
||||
.ops = &clkhwops_omap3_dpll,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(dpll_ddr_ck, dpll_core_ck_parents, dpll_ddr_ck_ops);
|
||||
|
||||
/*
|
||||
* TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
|
||||
* and ALT_CLK1/2)
|
||||
*/
|
||||
DEFINE_CLK_DIVIDER(dpll_ddr_m2_ck, "dpll_ddr_ck", &dpll_ddr_ck,
|
||||
0x0, AM33XX_CM_DIV_M2_DPLL_DDR,
|
||||
AM33XX_DPLL_CLKOUT_DIV_SHIFT, AM33XX_DPLL_CLKOUT_DIV_WIDTH,
|
||||
CLK_DIVIDER_ONE_BASED, NULL);
|
||||
|
||||
/* emif_fck functional clock */
|
||||
DEFINE_CLK_FIXED_FACTOR(dpll_ddr_m2_div2_ck, "dpll_ddr_m2_ck", &dpll_ddr_m2_ck,
|
||||
0x0, 1, 2);
|
||||
|
||||
/* DPLL_DISP */
|
||||
static struct dpll_data dpll_disp_dd = {
|
||||
.mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_DISP,
|
||||
.clk_bypass = &sys_clkin_ck,
|
||||
.clk_ref = &sys_clkin_ck,
|
||||
.control_reg = AM33XX_CM_CLKMODE_DPLL_DISP,
|
||||
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
|
||||
.idlest_reg = AM33XX_CM_IDLEST_DPLL_DISP,
|
||||
.mult_mask = AM33XX_DPLL_MULT_MASK,
|
||||
.div1_mask = AM33XX_DPLL_DIV_MASK,
|
||||
.enable_mask = AM33XX_DPLL_EN_MASK,
|
||||
.idlest_mask = AM33XX_ST_DPLL_CLK_MASK,
|
||||
.max_multiplier = 2047,
|
||||
.max_divider = 128,
|
||||
.min_divider = 1,
|
||||
};
|
||||
|
||||
/* CLKOUT: fdpll/M2 */
|
||||
static struct clk dpll_disp_ck;
|
||||
|
||||
static struct clk_hw_omap dpll_disp_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &dpll_disp_ck,
|
||||
},
|
||||
.dpll_data = &dpll_disp_dd,
|
||||
.ops = &clkhwops_omap3_dpll,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(dpll_disp_ck, dpll_core_ck_parents, dpll_ddr_ck_ops);
|
||||
|
||||
/*
|
||||
* TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
|
||||
* and ALT_CLK1/2)
|
||||
*/
|
||||
DEFINE_CLK_DIVIDER(dpll_disp_m2_ck, "dpll_disp_ck", &dpll_disp_ck, 0x0,
|
||||
AM33XX_CM_DIV_M2_DPLL_DISP, AM33XX_DPLL_CLKOUT_DIV_SHIFT,
|
||||
AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
|
||||
|
||||
/* DPLL_PER */
|
||||
static struct dpll_data dpll_per_dd = {
|
||||
.mult_div1_reg = AM33XX_CM_CLKSEL_DPLL_PERIPH,
|
||||
.clk_bypass = &sys_clkin_ck,
|
||||
.clk_ref = &sys_clkin_ck,
|
||||
.control_reg = AM33XX_CM_CLKMODE_DPLL_PER,
|
||||
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
|
||||
.idlest_reg = AM33XX_CM_IDLEST_DPLL_PER,
|
||||
.mult_mask = AM33XX_DPLL_MULT_PERIPH_MASK,
|
||||
.div1_mask = AM33XX_DPLL_PER_DIV_MASK,
|
||||
.enable_mask = AM33XX_DPLL_EN_MASK,
|
||||
.idlest_mask = AM33XX_ST_DPLL_CLK_MASK,
|
||||
.max_multiplier = 2047,
|
||||
.max_divider = 128,
|
||||
.min_divider = 1,
|
||||
.flags = DPLL_J_TYPE,
|
||||
};
|
||||
|
||||
/* CLKDCOLDO */
|
||||
static struct clk dpll_per_ck;
|
||||
|
||||
static struct clk_hw_omap dpll_per_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &dpll_per_ck,
|
||||
},
|
||||
.dpll_data = &dpll_per_dd,
|
||||
.ops = &clkhwops_omap3_dpll,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(dpll_per_ck, dpll_core_ck_parents, dpll_ddr_ck_ops);
|
||||
|
||||
/* CLKOUT: fdpll/M2 */
|
||||
DEFINE_CLK_DIVIDER(dpll_per_m2_ck, "dpll_per_ck", &dpll_per_ck, 0x0,
|
||||
AM33XX_CM_DIV_M2_DPLL_PER, AM33XX_DPLL_CLKOUT_DIV_SHIFT,
|
||||
AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED,
|
||||
NULL);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(dpll_per_m2_div4_wkupdm_ck, "dpll_per_m2_ck",
|
||||
&dpll_per_m2_ck, 0x0, 1, 4);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(dpll_per_m2_div4_ck, "dpll_per_m2_ck",
|
||||
&dpll_per_m2_ck, 0x0, 1, 4);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(dpll_core_m4_div2_ck, "dpll_core_m4_ck",
|
||||
&dpll_core_m4_ck, 0x0, 1, 2);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(l4_rtc_gclk, "dpll_core_m4_ck", &dpll_core_m4_ck, 0x0,
|
||||
1, 2);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(clk_24mhz, "dpll_per_m2_ck", &dpll_per_m2_ck, 0x0, 1,
|
||||
8);
|
||||
|
||||
/*
|
||||
* Below clock nodes describes clockdomains derived out
|
||||
* of core clock.
|
||||
*/
|
||||
static const struct clk_ops clk_ops_null = {
|
||||
};
|
||||
|
||||
static const char *l3_gclk_parents[] = {
|
||||
"dpll_core_m4_ck"
|
||||
};
|
||||
|
||||
static struct clk l3_gclk;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(l3_gclk, NULL);
|
||||
DEFINE_STRUCT_CLK(l3_gclk, l3_gclk_parents, clk_ops_null);
|
||||
|
||||
static struct clk l4hs_gclk;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(l4hs_gclk, NULL);
|
||||
DEFINE_STRUCT_CLK(l4hs_gclk, l3_gclk_parents, clk_ops_null);
|
||||
|
||||
static const char *l3s_gclk_parents[] = {
|
||||
"dpll_core_m4_div2_ck"
|
||||
};
|
||||
|
||||
static struct clk l3s_gclk;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(l3s_gclk, NULL);
|
||||
DEFINE_STRUCT_CLK(l3s_gclk, l3s_gclk_parents, clk_ops_null);
|
||||
|
||||
static struct clk l4fw_gclk;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(l4fw_gclk, NULL);
|
||||
DEFINE_STRUCT_CLK(l4fw_gclk, l3s_gclk_parents, clk_ops_null);
|
||||
|
||||
static struct clk l4ls_gclk;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(l4ls_gclk, NULL);
|
||||
DEFINE_STRUCT_CLK(l4ls_gclk, l3s_gclk_parents, clk_ops_null);
|
||||
|
||||
static struct clk sysclk_div_ck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(sysclk_div_ck, NULL);
|
||||
DEFINE_STRUCT_CLK(sysclk_div_ck, l3_gclk_parents, clk_ops_null);
|
||||
|
||||
/*
|
||||
* In order to match the clock domain with hwmod clockdomain entry,
|
||||
* separate clock nodes is required for the modules which are
|
||||
* directly getting their funtioncal clock from sys_clkin.
|
||||
*/
|
||||
static struct clk adc_tsc_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(adc_tsc_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(adc_tsc_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
static struct clk dcan0_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(dcan0_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(dcan0_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
static struct clk dcan1_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(dcan1_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(dcan1_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
static struct clk mcasp0_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(mcasp0_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(mcasp0_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
static struct clk mcasp1_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(mcasp1_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(mcasp1_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
static struct clk smartreflex0_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(smartreflex0_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(smartreflex0_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
static struct clk smartreflex1_fck;
|
||||
DEFINE_STRUCT_CLK_HW_OMAP(smartreflex1_fck, NULL);
|
||||
DEFINE_STRUCT_CLK(smartreflex1_fck, dpll_core_ck_parents, clk_ops_null);
|
||||
|
||||
/*
|
||||
* Modules clock nodes
|
||||
*
|
||||
* The following clock leaf nodes are added for the moment because:
|
||||
*
|
||||
* - hwmod data is not present for these modules, either hwmod
|
||||
* control is not required or its not populated.
|
||||
* - Driver code is not yet migrated to use hwmod/runtime pm
|
||||
* - Modules outside kernel access (to disable them by default)
|
||||
*
|
||||
* - debugss
|
||||
* - mmu (gfx domain)
|
||||
* - cefuse
|
||||
* - usbotg_fck (its additional clock and not really a modulemode)
|
||||
* - ieee5000
|
||||
*/
|
||||
DEFINE_CLK_GATE(debugss_ick, "dpll_core_m4_ck", &dpll_core_m4_ck, 0x0,
|
||||
AM33XX_CM_WKUP_DEBUGSS_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
|
||||
0x0, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(mmu_fck, "dpll_core_m4_ck", &dpll_core_m4_ck, 0x0,
|
||||
AM33XX_CM_GFX_MMUDATA_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
|
||||
0x0, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(cefuse_fck, "sys_clkin_ck", &sys_clkin_ck, 0x0,
|
||||
AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
|
||||
0x0, NULL);
|
||||
|
||||
/*
|
||||
* clkdiv32 is generated from fixed division of 732.4219
|
||||
*/
|
||||
DEFINE_CLK_FIXED_FACTOR(clkdiv32k_ck, "clk_24mhz", &clk_24mhz, 0x0, 1, 732);
|
||||
|
||||
DEFINE_CLK_GATE(clkdiv32k_ick, "clkdiv32k_ck", &clkdiv32k_ck, 0x0,
|
||||
AM33XX_CM_PER_CLKDIV32K_CLKCTRL, AM33XX_MODULEMODE_SWCTRL_SHIFT,
|
||||
0x0, NULL);
|
||||
|
||||
/* "usbotg_fck" is an additional clock and not really a modulemode */
|
||||
DEFINE_CLK_GATE(usbotg_fck, "dpll_per_ck", &dpll_per_ck, 0x0,
|
||||
AM33XX_CM_CLKDCOLDO_DPLL_PER, AM33XX_ST_DPLL_CLKDCOLDO_SHIFT,
|
||||
0x0, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(ieee5000_fck, "dpll_core_m4_div2_ck", &dpll_core_m4_div2_ck,
|
||||
0x0, AM33XX_CM_PER_IEEE5000_CLKCTRL,
|
||||
AM33XX_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL);
|
||||
|
||||
/* Timers */
|
||||
static const struct clksel timer1_clkmux_sel[] = {
|
||||
{ .parent = &sys_clkin_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &clkdiv32k_ick, .rates = div_1_1_rates },
|
||||
{ .parent = &tclkin_ck, .rates = div_1_2_rates },
|
||||
{ .parent = &clk_rc32k_ck, .rates = div_1_3_rates },
|
||||
{ .parent = &clk_32768_ck, .rates = div_1_4_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static const char *timer1_ck_parents[] = {
|
||||
"sys_clkin_ck", "clkdiv32k_ick", "tclkin_ck", "clk_rc32k_ck",
|
||||
"clk_32768_ck",
|
||||
};
|
||||
|
||||
static struct clk timer1_fck;
|
||||
|
||||
static const struct clk_ops timer1_fck_ops = {
|
||||
.recalc_rate = &omap2_clksel_recalc,
|
||||
.get_parent = &omap2_clksel_find_parent_index,
|
||||
.set_parent = &omap2_clksel_set_parent,
|
||||
.init = &omap2_init_clk_clkdm,
|
||||
};
|
||||
|
||||
static struct clk_hw_omap timer1_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer1_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer1_clkmux_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER1MS_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_2_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer1_fck, timer1_ck_parents, timer1_fck_ops);
|
||||
|
||||
static const struct clksel timer2_to_7_clk_sel[] = {
|
||||
{ .parent = &tclkin_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &sys_clkin_ck, .rates = div_1_1_rates },
|
||||
{ .parent = &clkdiv32k_ick, .rates = div_1_2_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static const char *timer2_to_7_ck_parents[] = {
|
||||
"tclkin_ck", "sys_clkin_ck", "clkdiv32k_ick",
|
||||
};
|
||||
|
||||
static struct clk timer2_fck;
|
||||
|
||||
static struct clk_hw_omap timer2_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer2_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer2_to_7_clk_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER2_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer2_fck, timer2_to_7_ck_parents, timer1_fck_ops);
|
||||
|
||||
static struct clk timer3_fck;
|
||||
|
||||
static struct clk_hw_omap timer3_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer3_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer2_to_7_clk_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER3_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer3_fck, timer2_to_7_ck_parents, timer1_fck_ops);
|
||||
|
||||
static struct clk timer4_fck;
|
||||
|
||||
static struct clk_hw_omap timer4_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer4_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer2_to_7_clk_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER4_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer4_fck, timer2_to_7_ck_parents, timer1_fck_ops);
|
||||
|
||||
static struct clk timer5_fck;
|
||||
|
||||
static struct clk_hw_omap timer5_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer5_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer2_to_7_clk_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER5_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer5_fck, timer2_to_7_ck_parents, timer1_fck_ops);
|
||||
|
||||
static struct clk timer6_fck;
|
||||
|
||||
static struct clk_hw_omap timer6_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer6_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer2_to_7_clk_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER6_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer6_fck, timer2_to_7_ck_parents, timer1_fck_ops);
|
||||
|
||||
static struct clk timer7_fck;
|
||||
|
||||
static struct clk_hw_omap timer7_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &timer7_fck,
|
||||
},
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.clksel = timer2_to_7_clk_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_TIMER7_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(timer7_fck, timer2_to_7_ck_parents, timer1_fck_ops);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(cpsw_125mhz_gclk,
|
||||
"dpll_core_m5_ck",
|
||||
&dpll_core_m5_ck,
|
||||
0x0,
|
||||
1, 2);
|
||||
|
||||
static const struct clk_ops cpsw_fck_ops = {
|
||||
.recalc_rate = &omap2_clksel_recalc,
|
||||
.get_parent = &omap2_clksel_find_parent_index,
|
||||
.set_parent = &omap2_clksel_set_parent,
|
||||
};
|
||||
|
||||
static const struct clksel cpsw_cpts_rft_clkmux_sel[] = {
|
||||
{ .parent = &dpll_core_m5_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &dpll_core_m4_ck, .rates = div_1_1_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static const char *cpsw_cpts_rft_ck_parents[] = {
|
||||
"dpll_core_m5_ck", "dpll_core_m4_ck",
|
||||
};
|
||||
|
||||
static struct clk cpsw_cpts_rft_clk;
|
||||
|
||||
static struct clk_hw_omap cpsw_cpts_rft_clk_hw = {
|
||||
.hw = {
|
||||
.clk = &cpsw_cpts_rft_clk,
|
||||
},
|
||||
.clkdm_name = "cpsw_125mhz_clkdm",
|
||||
.clksel = cpsw_cpts_rft_clkmux_sel,
|
||||
.clksel_reg = AM33XX_CM_CPTS_RFT_CLKSEL,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_0_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(cpsw_cpts_rft_clk, cpsw_cpts_rft_ck_parents, cpsw_fck_ops);
|
||||
|
||||
|
||||
/* gpio */
|
||||
static const char *gpio0_ck_parents[] = {
|
||||
"clk_rc32k_ck", "clk_32768_ck", "clkdiv32k_ick",
|
||||
};
|
||||
|
||||
static const struct clksel gpio0_dbclk_mux_sel[] = {
|
||||
{ .parent = &clk_rc32k_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &clk_32768_ck, .rates = div_1_1_rates },
|
||||
{ .parent = &clkdiv32k_ick, .rates = div_1_2_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static const struct clk_ops gpio_fck_ops = {
|
||||
.recalc_rate = &omap2_clksel_recalc,
|
||||
.get_parent = &omap2_clksel_find_parent_index,
|
||||
.set_parent = &omap2_clksel_set_parent,
|
||||
.init = &omap2_init_clk_clkdm,
|
||||
};
|
||||
|
||||
static struct clk gpio0_dbclk_mux_ck;
|
||||
|
||||
static struct clk_hw_omap gpio0_dbclk_mux_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &gpio0_dbclk_mux_ck,
|
||||
},
|
||||
.clkdm_name = "l4_wkup_clkdm",
|
||||
.clksel = gpio0_dbclk_mux_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_GPIO0_DBCLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(gpio0_dbclk_mux_ck, gpio0_ck_parents, gpio_fck_ops);
|
||||
|
||||
DEFINE_CLK_GATE(gpio0_dbclk, "gpio0_dbclk_mux_ck", &gpio0_dbclk_mux_ck, 0x0,
|
||||
AM33XX_CM_WKUP_GPIO0_CLKCTRL,
|
||||
AM33XX_OPTFCLKEN_GPIO0_GDBCLK_SHIFT, 0x0, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(gpio1_dbclk, "clkdiv32k_ick", &clkdiv32k_ick, 0x0,
|
||||
AM33XX_CM_PER_GPIO1_CLKCTRL,
|
||||
AM33XX_OPTFCLKEN_GPIO_1_GDBCLK_SHIFT, 0x0, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(gpio2_dbclk, "clkdiv32k_ick", &clkdiv32k_ick, 0x0,
|
||||
AM33XX_CM_PER_GPIO2_CLKCTRL,
|
||||
AM33XX_OPTFCLKEN_GPIO_2_GDBCLK_SHIFT, 0x0, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(gpio3_dbclk, "clkdiv32k_ick", &clkdiv32k_ick, 0x0,
|
||||
AM33XX_CM_PER_GPIO3_CLKCTRL,
|
||||
AM33XX_OPTFCLKEN_GPIO_3_GDBCLK_SHIFT, 0x0, NULL);
|
||||
|
||||
|
||||
static const char *pruss_ck_parents[] = {
|
||||
"l3_gclk", "dpll_disp_m2_ck",
|
||||
};
|
||||
|
||||
static const struct clksel pruss_ocp_clk_mux_sel[] = {
|
||||
{ .parent = &l3_gclk, .rates = div_1_0_rates },
|
||||
{ .parent = &dpll_disp_m2_ck, .rates = div_1_1_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static struct clk pruss_ocp_gclk;
|
||||
|
||||
static struct clk_hw_omap pruss_ocp_gclk_hw = {
|
||||
.hw = {
|
||||
.clk = &pruss_ocp_gclk,
|
||||
},
|
||||
.clkdm_name = "pruss_ocp_clkdm",
|
||||
.clksel = pruss_ocp_clk_mux_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_PRUSS_OCP_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_0_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(pruss_ocp_gclk, pruss_ck_parents, gpio_fck_ops);
|
||||
|
||||
static const char *lcd_ck_parents[] = {
|
||||
"dpll_disp_m2_ck", "dpll_core_m5_ck", "dpll_per_m2_ck",
|
||||
};
|
||||
|
||||
static const struct clksel lcd_clk_mux_sel[] = {
|
||||
{ .parent = &dpll_disp_m2_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &dpll_core_m5_ck, .rates = div_1_1_rates },
|
||||
{ .parent = &dpll_per_m2_ck, .rates = div_1_2_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static struct clk lcd_gclk;
|
||||
|
||||
static struct clk_hw_omap lcd_gclk_hw = {
|
||||
.hw = {
|
||||
.clk = &lcd_gclk,
|
||||
},
|
||||
.clkdm_name = "lcdc_clkdm",
|
||||
.clksel = lcd_clk_mux_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_LCDC_PIXEL_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(lcd_gclk, lcd_ck_parents, gpio_fck_ops);
|
||||
|
||||
DEFINE_CLK_FIXED_FACTOR(mmc_clk, "dpll_per_m2_ck", &dpll_per_m2_ck, 0x0, 1, 2);
|
||||
|
||||
static const char *gfx_ck_parents[] = {
|
||||
"dpll_core_m4_ck", "dpll_per_m2_ck",
|
||||
};
|
||||
|
||||
static const struct clksel gfx_clksel_sel[] = {
|
||||
{ .parent = &dpll_core_m4_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &dpll_per_m2_ck, .rates = div_1_1_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static struct clk gfx_fclk_clksel_ck;
|
||||
|
||||
static struct clk_hw_omap gfx_fclk_clksel_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &gfx_fclk_clksel_ck,
|
||||
},
|
||||
.clksel = gfx_clksel_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_GFX_FCLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_GFX_FCLK_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(gfx_fclk_clksel_ck, gfx_ck_parents, gpio_fck_ops);
|
||||
|
||||
static const struct clk_div_table div_1_0_2_1_rates[] = {
|
||||
{ .div = 1, .val = 0, },
|
||||
{ .div = 2, .val = 1, },
|
||||
{ .div = 0 },
|
||||
};
|
||||
|
||||
DEFINE_CLK_DIVIDER_TABLE(gfx_fck_div_ck, "gfx_fclk_clksel_ck",
|
||||
&gfx_fclk_clksel_ck, 0x0, AM33XX_CLKSEL_GFX_FCLK,
|
||||
AM33XX_CLKSEL_0_0_SHIFT, AM33XX_CLKSEL_0_0_WIDTH,
|
||||
0x0, div_1_0_2_1_rates, NULL);
|
||||
|
||||
static const char *sysclkout_ck_parents[] = {
|
||||
"clk_32768_ck", "l3_gclk", "dpll_ddr_m2_ck", "dpll_per_m2_ck",
|
||||
"lcd_gclk",
|
||||
};
|
||||
|
||||
static const struct clksel sysclkout_pre_sel[] = {
|
||||
{ .parent = &clk_32768_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &l3_gclk, .rates = div_1_1_rates },
|
||||
{ .parent = &dpll_ddr_m2_ck, .rates = div_1_2_rates },
|
||||
{ .parent = &dpll_per_m2_ck, .rates = div_1_3_rates },
|
||||
{ .parent = &lcd_gclk, .rates = div_1_4_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static struct clk sysclkout_pre_ck;
|
||||
|
||||
static struct clk_hw_omap sysclkout_pre_ck_hw = {
|
||||
.hw = {
|
||||
.clk = &sysclkout_pre_ck,
|
||||
},
|
||||
.clksel = sysclkout_pre_sel,
|
||||
.clksel_reg = AM33XX_CM_CLKOUT_CTRL,
|
||||
.clksel_mask = AM33XX_CLKOUT2SOURCE_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(sysclkout_pre_ck, sysclkout_ck_parents, gpio_fck_ops);
|
||||
|
||||
/* Divide by 8 clock rates with default clock is 1/1*/
|
||||
static const struct clk_div_table div8_rates[] = {
|
||||
{ .div = 1, .val = 0, },
|
||||
{ .div = 2, .val = 1, },
|
||||
{ .div = 3, .val = 2, },
|
||||
{ .div = 4, .val = 3, },
|
||||
{ .div = 5, .val = 4, },
|
||||
{ .div = 6, .val = 5, },
|
||||
{ .div = 7, .val = 6, },
|
||||
{ .div = 8, .val = 7, },
|
||||
{ .div = 0 },
|
||||
};
|
||||
|
||||
DEFINE_CLK_DIVIDER_TABLE(clkout2_div_ck, "sysclkout_pre_ck", &sysclkout_pre_ck,
|
||||
0x0, AM33XX_CM_CLKOUT_CTRL, AM33XX_CLKOUT2DIV_SHIFT,
|
||||
AM33XX_CLKOUT2DIV_WIDTH, 0x0, div8_rates, NULL);
|
||||
|
||||
DEFINE_CLK_GATE(clkout2_ck, "clkout2_div_ck", &clkout2_div_ck, 0x0,
|
||||
AM33XX_CM_CLKOUT_CTRL, AM33XX_CLKOUT2EN_SHIFT, 0x0, NULL);
|
||||
|
||||
static const char *wdt_ck_parents[] = {
|
||||
"clk_rc32k_ck", "clkdiv32k_ick",
|
||||
};
|
||||
|
||||
static const struct clksel wdt_clkmux_sel[] = {
|
||||
{ .parent = &clk_rc32k_ck, .rates = div_1_0_rates },
|
||||
{ .parent = &clkdiv32k_ick, .rates = div_1_1_rates },
|
||||
{ .parent = NULL },
|
||||
};
|
||||
|
||||
static struct clk wdt1_fck;
|
||||
|
||||
static struct clk_hw_omap wdt1_fck_hw = {
|
||||
.hw = {
|
||||
.clk = &wdt1_fck,
|
||||
},
|
||||
.clkdm_name = "l4_wkup_clkdm",
|
||||
.clksel = wdt_clkmux_sel,
|
||||
.clksel_reg = AM33XX_CLKSEL_WDT1_CLK,
|
||||
.clksel_mask = AM33XX_CLKSEL_0_1_MASK,
|
||||
};
|
||||
|
||||
DEFINE_STRUCT_CLK(wdt1_fck, wdt_ck_parents, gpio_fck_ops);
|
||||
|
||||
/*
|
||||
* clkdev
|
||||
*/
|
||||
static struct omap_clk am33xx_clks[] = {
|
||||
CLK(NULL, "clk_32768_ck", &clk_32768_ck, CK_AM33XX),
|
||||
CLK(NULL, "clk_rc32k_ck", &clk_rc32k_ck, CK_AM33XX),
|
||||
CLK(NULL, "virt_19200000_ck", &virt_19200000_ck, CK_AM33XX),
|
||||
CLK(NULL, "virt_24000000_ck", &virt_24000000_ck, CK_AM33XX),
|
||||
CLK(NULL, "virt_25000000_ck", &virt_25000000_ck, CK_AM33XX),
|
||||
CLK(NULL, "virt_26000000_ck", &virt_26000000_ck, CK_AM33XX),
|
||||
CLK(NULL, "sys_clkin_ck", &sys_clkin_ck, CK_AM33XX),
|
||||
CLK(NULL, "tclkin_ck", &tclkin_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_core_ck", &dpll_core_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_core_x2_ck", &dpll_core_x2_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_core_m4_ck", &dpll_core_m4_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_core_m5_ck", &dpll_core_m5_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_core_m6_ck", &dpll_core_m6_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_mpu_ck", &dpll_mpu_ck, CK_AM33XX),
|
||||
CLK("cpu0", NULL, &dpll_mpu_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_mpu_m2_ck", &dpll_mpu_m2_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_ddr_ck", &dpll_ddr_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_ddr_m2_ck", &dpll_ddr_m2_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_ddr_m2_div2_ck", &dpll_ddr_m2_div2_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_disp_ck", &dpll_disp_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_disp_m2_ck", &dpll_disp_m2_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_per_ck", &dpll_per_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_per_m2_ck", &dpll_per_m2_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_per_m2_div4_wkupdm_ck", &dpll_per_m2_div4_wkupdm_ck, CK_AM33XX),
|
||||
CLK(NULL, "dpll_per_m2_div4_ck", &dpll_per_m2_div4_ck, CK_AM33XX),
|
||||
CLK(NULL, "adc_tsc_fck", &adc_tsc_fck, CK_AM33XX),
|
||||
CLK(NULL, "cefuse_fck", &cefuse_fck, CK_AM33XX),
|
||||
CLK(NULL, "clkdiv32k_ck", &clkdiv32k_ck, CK_AM33XX),
|
||||
CLK(NULL, "clkdiv32k_ick", &clkdiv32k_ick, CK_AM33XX),
|
||||
CLK(NULL, "dcan0_fck", &dcan0_fck, CK_AM33XX),
|
||||
CLK("481cc000.d_can", NULL, &dcan0_fck, CK_AM33XX),
|
||||
CLK(NULL, "dcan1_fck", &dcan1_fck, CK_AM33XX),
|
||||
CLK("481d0000.d_can", NULL, &dcan1_fck, CK_AM33XX),
|
||||
CLK(NULL, "debugss_ick", &debugss_ick, CK_AM33XX),
|
||||
CLK(NULL, "pruss_ocp_gclk", &pruss_ocp_gclk, CK_AM33XX),
|
||||
CLK(NULL, "mcasp0_fck", &mcasp0_fck, CK_AM33XX),
|
||||
CLK(NULL, "mcasp1_fck", &mcasp1_fck, CK_AM33XX),
|
||||
CLK(NULL, "mmu_fck", &mmu_fck, CK_AM33XX),
|
||||
CLK(NULL, "smartreflex0_fck", &smartreflex0_fck, CK_AM33XX),
|
||||
CLK(NULL, "smartreflex1_fck", &smartreflex1_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer1_fck", &timer1_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer2_fck", &timer2_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer3_fck", &timer3_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer4_fck", &timer4_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer5_fck", &timer5_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer6_fck", &timer6_fck, CK_AM33XX),
|
||||
CLK(NULL, "timer7_fck", &timer7_fck, CK_AM33XX),
|
||||
CLK(NULL, "usbotg_fck", &usbotg_fck, CK_AM33XX),
|
||||
CLK(NULL, "ieee5000_fck", &ieee5000_fck, CK_AM33XX),
|
||||
CLK(NULL, "wdt1_fck", &wdt1_fck, CK_AM33XX),
|
||||
CLK(NULL, "l4_rtc_gclk", &l4_rtc_gclk, CK_AM33XX),
|
||||
CLK(NULL, "l3_gclk", &l3_gclk, CK_AM33XX),
|
||||
CLK(NULL, "dpll_core_m4_div2_ck", &dpll_core_m4_div2_ck, CK_AM33XX),
|
||||
CLK(NULL, "l4hs_gclk", &l4hs_gclk, CK_AM33XX),
|
||||
CLK(NULL, "l3s_gclk", &l3s_gclk, CK_AM33XX),
|
||||
CLK(NULL, "l4fw_gclk", &l4fw_gclk, CK_AM33XX),
|
||||
CLK(NULL, "l4ls_gclk", &l4ls_gclk, CK_AM33XX),
|
||||
CLK(NULL, "clk_24mhz", &clk_24mhz, CK_AM33XX),
|
||||
CLK(NULL, "sysclk_div_ck", &sysclk_div_ck, CK_AM33XX),
|
||||
CLK(NULL, "cpsw_125mhz_gclk", &cpsw_125mhz_gclk, CK_AM33XX),
|
||||
CLK(NULL, "cpsw_cpts_rft_clk", &cpsw_cpts_rft_clk, CK_AM33XX),
|
||||
CLK(NULL, "gpio0_dbclk_mux_ck", &gpio0_dbclk_mux_ck, CK_AM33XX),
|
||||
CLK(NULL, "gpio0_dbclk", &gpio0_dbclk, CK_AM33XX),
|
||||
CLK(NULL, "gpio1_dbclk", &gpio1_dbclk, CK_AM33XX),
|
||||
CLK(NULL, "gpio2_dbclk", &gpio2_dbclk, CK_AM33XX),
|
||||
CLK(NULL, "gpio3_dbclk", &gpio3_dbclk, CK_AM33XX),
|
||||
CLK(NULL, "lcd_gclk", &lcd_gclk, CK_AM33XX),
|
||||
CLK(NULL, "mmc_clk", &mmc_clk, CK_AM33XX),
|
||||
CLK(NULL, "gfx_fclk_clksel_ck", &gfx_fclk_clksel_ck, CK_AM33XX),
|
||||
CLK(NULL, "gfx_fck_div_ck", &gfx_fck_div_ck, CK_AM33XX),
|
||||
CLK(NULL, "sysclkout_pre_ck", &sysclkout_pre_ck, CK_AM33XX),
|
||||
CLK(NULL, "clkout2_div_ck", &clkout2_div_ck, CK_AM33XX),
|
||||
CLK(NULL, "timer_32k_ck", &clkdiv32k_ick, CK_AM33XX),
|
||||
CLK(NULL, "timer_sys_ck", &sys_clkin_ck, CK_AM33XX),
|
||||
};
|
||||
|
||||
|
||||
static const char *enable_init_clks[] = {
|
||||
"dpll_ddr_m2_ck",
|
||||
"dpll_mpu_m2_ck",
|
||||
"l3_gclk",
|
||||
"l4hs_gclk",
|
||||
"l4fw_gclk",
|
||||
"l4ls_gclk",
|
||||
};
|
||||
|
||||
int __init am33xx_clk_init(void)
|
||||
{
|
||||
struct omap_clk *c;
|
||||
u32 cpu_clkflg;
|
||||
|
||||
if (soc_is_am33xx()) {
|
||||
cpu_mask = RATE_IN_AM33XX;
|
||||
cpu_clkflg = CK_AM33XX;
|
||||
}
|
||||
|
||||
for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++) {
|
||||
if (c->cpu & cpu_clkflg) {
|
||||
clkdev_add(&c->lk);
|
||||
if (!__clk_init(NULL, c->lk.clk))
|
||||
omap2_init_clk_hw_omap_clocks(c->lk.clk);
|
||||
}
|
||||
}
|
||||
|
||||
omap2_clk_disable_autoidle_all();
|
||||
|
||||
omap2_clk_enable_init_clocks(enable_init_clks,
|
||||
ARRAY_SIZE(enable_init_clks));
|
||||
|
||||
/* TRM ERRATA: Timer 3 & 6 default parent (TCLKIN) may not be always
|
||||
* physically present, in such a case HWMOD enabling of
|
||||
* clock would be failure with default parent. And timer
|
||||
* probe thinks clock is already enabled, this leads to
|
||||
* crash upon accessing timer 3 & 6 registers in probe.
|
||||
* Fix by setting parent of both these timers to master
|
||||
* oscillator clock.
|
||||
*/
|
||||
|
||||
clk_set_parent(&timer3_fck, &sys_clkin_ck);
|
||||
clk_set_parent(&timer6_fck, &sys_clkin_ck);
|
||||
|
||||
return 0;
|
||||
}
|
3595
arch/arm/mach-omap2/cclock3xxx_data.c
Normal file
3595
arch/arm/mach-omap2/cclock3xxx_data.c
Normal file
File diff suppressed because it is too large
Load diff
1987
arch/arm/mach-omap2/cclock44xx_data.c
Normal file
1987
arch/arm/mach-omap2/cclock44xx_data.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -21,11 +21,10 @@
|
|||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/prcm.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
#include "cm2xxx.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
|
||||
/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
|
||||
|
@ -37,92 +36,90 @@
|
|||
#define APLLS_CLKIN_13MHZ 2
|
||||
#define APLLS_CLKIN_12MHZ 3
|
||||
|
||||
void __iomem *cm_idlest_pll;
|
||||
|
||||
/* Private functions */
|
||||
|
||||
/* Enable an APLL if off */
|
||||
static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
|
||||
/**
|
||||
* omap2xxx_clk_apll_locked - is the APLL locked?
|
||||
* @hw: struct clk_hw * of the APLL to check
|
||||
*
|
||||
* If the APLL IP block referred to by @hw indicates that it's locked,
|
||||
* return true; otherwise, return false.
|
||||
*/
|
||||
static bool omap2xxx_clk_apll_locked(struct clk_hw *hw)
|
||||
{
|
||||
u32 cval, apll_mask;
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 r, apll_mask;
|
||||
|
||||
apll_mask = EN_APLL_LOCKED << clk->enable_bit;
|
||||
|
||||
cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
|
||||
r = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
|
||||
|
||||
if ((cval & apll_mask) == apll_mask)
|
||||
return 0; /* apll already enabled */
|
||||
|
||||
cval &= ~apll_mask;
|
||||
cval |= apll_mask;
|
||||
omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
|
||||
|
||||
omap2_cm_wait_idlest(cm_idlest_pll, status_mask,
|
||||
OMAP24XX_CM_IDLEST_VAL, __clk_get_name(clk));
|
||||
|
||||
/*
|
||||
* REVISIT: Should we return an error code if omap2_wait_clock_ready()
|
||||
* fails?
|
||||
*/
|
||||
return 0;
|
||||
return ((r & apll_mask) == apll_mask) ? true : false;
|
||||
}
|
||||
|
||||
static int omap2_clk_apll96_enable(struct clk *clk)
|
||||
int omap2_clk_apll96_enable(struct clk_hw *hw)
|
||||
{
|
||||
return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL_MASK);
|
||||
return omap2xxx_cm_apll96_enable();
|
||||
}
|
||||
|
||||
static int omap2_clk_apll54_enable(struct clk *clk)
|
||||
int omap2_clk_apll54_enable(struct clk_hw *hw)
|
||||
{
|
||||
return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL_MASK);
|
||||
return omap2xxx_cm_apll54_enable();
|
||||
}
|
||||
|
||||
static void _apll96_allow_idle(struct clk *clk)
|
||||
static void _apll96_allow_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
omap2xxx_cm_set_apll96_auto_low_power_stop();
|
||||
}
|
||||
|
||||
static void _apll96_deny_idle(struct clk *clk)
|
||||
static void _apll96_deny_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
omap2xxx_cm_set_apll96_disable_autoidle();
|
||||
}
|
||||
|
||||
static void _apll54_allow_idle(struct clk *clk)
|
||||
static void _apll54_allow_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
omap2xxx_cm_set_apll54_auto_low_power_stop();
|
||||
}
|
||||
|
||||
static void _apll54_deny_idle(struct clk *clk)
|
||||
static void _apll54_deny_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
omap2xxx_cm_set_apll54_disable_autoidle();
|
||||
}
|
||||
|
||||
/* Stop APLL */
|
||||
static void omap2_clk_apll_disable(struct clk *clk)
|
||||
void omap2_clk_apll96_disable(struct clk_hw *hw)
|
||||
{
|
||||
u32 cval;
|
||||
omap2xxx_cm_apll96_disable();
|
||||
}
|
||||
|
||||
cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
|
||||
cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
|
||||
omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
|
||||
void omap2_clk_apll54_disable(struct clk_hw *hw)
|
||||
{
|
||||
omap2xxx_cm_apll54_disable();
|
||||
}
|
||||
|
||||
unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return (omap2xxx_clk_apll_locked(hw)) ? 54000000 : 0;
|
||||
}
|
||||
|
||||
unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return (omap2xxx_clk_apll_locked(hw)) ? 96000000 : 0;
|
||||
}
|
||||
|
||||
/* Public data */
|
||||
|
||||
const struct clkops clkops_apll96 = {
|
||||
.enable = omap2_clk_apll96_enable,
|
||||
.disable = omap2_clk_apll_disable,
|
||||
.allow_idle = _apll96_allow_idle,
|
||||
.deny_idle = _apll96_deny_idle,
|
||||
};
|
||||
|
||||
const struct clkops clkops_apll54 = {
|
||||
.enable = omap2_clk_apll54_enable,
|
||||
.disable = omap2_clk_apll_disable,
|
||||
const struct clk_hw_omap_ops clkhwops_apll54 = {
|
||||
.allow_idle = _apll54_allow_idle,
|
||||
.deny_idle = _apll54_deny_idle,
|
||||
};
|
||||
|
||||
const struct clk_hw_omap_ops clkhwops_apll96 = {
|
||||
.allow_idle = _apll96_allow_idle,
|
||||
.deny_idle = _apll96_deny_idle,
|
||||
};
|
||||
|
||||
/* Public functions */
|
||||
|
||||
u32 omap2xxx_get_apll_clkin(void)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <linux/io.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
#include "cm2xxx.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
|
||||
/* Private functions */
|
||||
|
@ -29,7 +29,7 @@
|
|||
* REVISIT: DPLL can optionally enter low-power bypass by writing 0x1
|
||||
* instead. Add some mechanism to optionally enter this mode.
|
||||
*/
|
||||
static void _allow_idle(struct clk *clk)
|
||||
static void _allow_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
if (!clk || !clk->dpll_data)
|
||||
return;
|
||||
|
@ -43,7 +43,7 @@ static void _allow_idle(struct clk *clk)
|
|||
*
|
||||
* Disable DPLL automatic idle control. No return value.
|
||||
*/
|
||||
static void _deny_idle(struct clk *clk)
|
||||
static void _deny_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
if (!clk || !clk->dpll_data)
|
||||
return;
|
||||
|
@ -53,9 +53,7 @@ static void _deny_idle(struct clk *clk)
|
|||
|
||||
|
||||
/* Public data */
|
||||
|
||||
const struct clkops clkops_omap2xxx_dpll_ops = {
|
||||
const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll = {
|
||||
.allow_idle = _allow_idle,
|
||||
.deny_idle = _deny_idle,
|
||||
};
|
||||
|
||||
|
|
|
@ -28,16 +28,22 @@
|
|||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
#include "opp2xxx.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
#include "cm2xxx.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
#include "sdrc.h"
|
||||
#include "sram.h"
|
||||
|
||||
/* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */
|
||||
|
||||
/*
|
||||
* dpll_core_ck: pointer to the combined dpll_ck + core_ck on OMAP2xxx
|
||||
* (currently defined as "dpll_ck" in the OMAP2xxx clock tree). Set
|
||||
* during dpll_ck init and used later by omap2xxx_clk_get_core_rate().
|
||||
*/
|
||||
static struct clk_hw_omap *dpll_core_ck;
|
||||
|
||||
/**
|
||||
* omap2xxx_clk_get_core_rate - return the CORE_CLK rate
|
||||
* @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
|
||||
*
|
||||
* Returns the CORE_CLK rate. CORE_CLK can have one of three rate
|
||||
* sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
|
||||
|
@ -45,12 +51,14 @@
|
|||
* struct clk *dpll_ck, which is a composite clock of dpll_ck and
|
||||
* core_ck.
|
||||
*/
|
||||
unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
|
||||
unsigned long omap2xxx_clk_get_core_rate(void)
|
||||
{
|
||||
long long core_clk;
|
||||
u32 v;
|
||||
|
||||
core_clk = omap2_get_dpll_rate(clk);
|
||||
WARN_ON(!dpll_core_ck);
|
||||
|
||||
core_clk = omap2_get_dpll_rate(dpll_core_ck);
|
||||
|
||||
v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
|
||||
v &= OMAP24XX_CORE_CLK_SRC_MASK;
|
||||
|
@ -96,19 +104,22 @@ static long omap2_dpllcore_round_rate(unsigned long target_rate)
|
|||
|
||||
}
|
||||
|
||||
unsigned long omap2_dpllcore_recalc(struct clk *clk)
|
||||
unsigned long omap2_dpllcore_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return omap2xxx_clk_get_core_rate(clk);
|
||||
return omap2xxx_clk_get_core_rate();
|
||||
}
|
||||
|
||||
int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
|
||||
int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 cur_rate, low, mult, div, valid_rate, done_rate;
|
||||
u32 bypass = 0;
|
||||
struct prcm_config tmpset;
|
||||
const struct dpll_data *dd;
|
||||
|
||||
cur_rate = omap2xxx_clk_get_core_rate(dclk);
|
||||
cur_rate = omap2xxx_clk_get_core_rate();
|
||||
mult = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
|
||||
mult &= OMAP24XX_CORE_CLK_SRC_MASK;
|
||||
|
||||
|
@ -169,3 +180,19 @@ int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2xxx_clkt_dpllcore_init - clk init function for dpll_ck
|
||||
* @clk: struct clk *dpll_ck
|
||||
*
|
||||
* Store a local copy of @clk in dpll_core_ck so other code can query
|
||||
* the core rate without having to clk_get(), which can sleep. Must
|
||||
* only be called once. No return value. XXX If the clock
|
||||
* registration process is ever changed such that dpll_ck is no longer
|
||||
* statically defined, this code may need to change to increment some
|
||||
* kind of use count on dpll_ck.
|
||||
*/
|
||||
void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw)
|
||||
{
|
||||
WARN(dpll_core_ck, "dpll_core_ck already set - should never happen");
|
||||
dpll_core_ck = to_clk_hw_omap(hw);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
* clk_enable/clk_disable()-based usecounting for osc_ck should be
|
||||
* replaced with autoidle-based usecounting.
|
||||
*/
|
||||
static int omap2_enable_osc_ck(struct clk *clk)
|
||||
int omap2_enable_osc_ck(struct clk_hw *clk)
|
||||
{
|
||||
u32 pcc;
|
||||
|
||||
|
@ -53,7 +53,7 @@ static int omap2_enable_osc_ck(struct clk *clk)
|
|||
* clk_enable/clk_disable()-based usecounting for osc_ck should be
|
||||
* replaced with autoidle-based usecounting.
|
||||
*/
|
||||
static void omap2_disable_osc_ck(struct clk *clk)
|
||||
void omap2_disable_osc_ck(struct clk_hw *clk)
|
||||
{
|
||||
u32 pcc;
|
||||
|
||||
|
@ -62,13 +62,8 @@ static void omap2_disable_osc_ck(struct clk *clk)
|
|||
__raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
|
||||
}
|
||||
|
||||
const struct clkops clkops_oscck = {
|
||||
.enable = omap2_enable_osc_ck,
|
||||
.disable = omap2_disable_osc_ck,
|
||||
};
|
||||
|
||||
unsigned long omap2_osc_clk_recalc(struct clk *clk)
|
||||
unsigned long omap2_osc_clk_recalc(struct clk_hw *clk,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return omap2xxx_get_apll_clkin() * omap2xxx_get_sysclkdiv();
|
||||
}
|
||||
|
||||
|
|
|
@ -40,9 +40,8 @@ u32 omap2xxx_get_sysclkdiv(void)
|
|||
return div;
|
||||
}
|
||||
|
||||
unsigned long omap2xxx_sys_clk_recalc(struct clk *clk)
|
||||
unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return clk->parent->rate / omap2xxx_get_sysclkdiv();
|
||||
return parent_rate / omap2xxx_get_sysclkdiv();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* OMAP2xxx DVFS virtual clock functions
|
||||
*
|
||||
* Copyright (C) 2005-2008 Texas Instruments, Inc.
|
||||
* Copyright (C) 2005-2008, 2012 Texas Instruments, Inc.
|
||||
* Copyright (C) 2004-2010 Nokia Corporation
|
||||
*
|
||||
* Contacts:
|
||||
|
@ -37,7 +37,7 @@
|
|||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
#include "opp2xxx.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
#include "cm2xxx.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
#include "sdrc.h"
|
||||
#include "sram.h"
|
||||
|
@ -45,13 +45,21 @@
|
|||
const struct prcm_config *curr_prcm_set;
|
||||
const struct prcm_config *rate_table;
|
||||
|
||||
/*
|
||||
* sys_ck_rate: the rate of the external high-frequency clock
|
||||
* oscillator on the board. Set by the SoC-specific clock init code.
|
||||
* Once set during a boot, will not change.
|
||||
*/
|
||||
static unsigned long sys_ck_rate;
|
||||
|
||||
/**
|
||||
* omap2_table_mpu_recalc - just return the MPU speed
|
||||
* @clk: virt_prcm_set struct clk
|
||||
*
|
||||
* Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
|
||||
*/
|
||||
unsigned long omap2_table_mpu_recalc(struct clk *clk)
|
||||
unsigned long omap2_table_mpu_recalc(struct clk_hw *clk,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
return curr_prcm_set->mpu_speed;
|
||||
}
|
||||
|
@ -63,18 +71,18 @@ unsigned long omap2_table_mpu_recalc(struct clk *clk)
|
|||
* Some might argue L3-DDR, others ARM, others IVA. This code is simple and
|
||||
* just uses the ARM rates.
|
||||
*/
|
||||
long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
|
||||
long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
const struct prcm_config *ptr;
|
||||
long highest_rate, sys_clk_rate;
|
||||
long highest_rate;
|
||||
|
||||
highest_rate = -EINVAL;
|
||||
sys_clk_rate = __clk_get_rate(sclk);
|
||||
|
||||
for (ptr = rate_table; ptr->mpu_speed; ptr++) {
|
||||
if (!(ptr->flags & cpu_mask))
|
||||
continue;
|
||||
if (ptr->xtal_speed != sys_clk_rate)
|
||||
if (ptr->xtal_speed != sys_ck_rate)
|
||||
continue;
|
||||
|
||||
highest_rate = ptr->mpu_speed;
|
||||
|
@ -87,21 +95,19 @@ long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
|
|||
}
|
||||
|
||||
/* Sets basic clocks based on the specified rate */
|
||||
int omap2_select_table_rate(struct clk *clk, unsigned long rate)
|
||||
int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
u32 cur_rate, done_rate, bypass = 0, tmp;
|
||||
const struct prcm_config *prcm;
|
||||
unsigned long found_speed = 0;
|
||||
unsigned long flags;
|
||||
long sys_clk_rate;
|
||||
|
||||
sys_clk_rate = __clk_get_rate(sclk);
|
||||
|
||||
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
|
||||
if (!(prcm->flags & cpu_mask))
|
||||
continue;
|
||||
|
||||
if (prcm->xtal_speed != sys_clk_rate)
|
||||
if (prcm->xtal_speed != sys_ck_rate)
|
||||
continue;
|
||||
|
||||
if (prcm->mpu_speed <= rate) {
|
||||
|
@ -117,7 +123,7 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
|
|||
}
|
||||
|
||||
curr_prcm_set = prcm;
|
||||
cur_rate = omap2xxx_clk_get_core_rate(dclk);
|
||||
cur_rate = omap2xxx_clk_get_core_rate();
|
||||
|
||||
if (prcm->dpll_speed == cur_rate / 2) {
|
||||
omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
|
||||
|
@ -167,3 +173,50 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2xxx_clkt_vps_check_bootloader_rate - determine which of the rate
|
||||
* table sets matches the current CORE DPLL hardware rate
|
||||
*
|
||||
* Check the MPU rate set by bootloader. Sets the 'curr_prcm_set'
|
||||
* global to point to the active rate set when found; otherwise, sets
|
||||
* it to NULL. No return value;
|
||||
*/
|
||||
void omap2xxx_clkt_vps_check_bootloader_rates(void)
|
||||
{
|
||||
const struct prcm_config *prcm = NULL;
|
||||
unsigned long rate;
|
||||
|
||||
rate = omap2xxx_clk_get_core_rate();
|
||||
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
|
||||
if (!(prcm->flags & cpu_mask))
|
||||
continue;
|
||||
if (prcm->xtal_speed != sys_ck_rate)
|
||||
continue;
|
||||
if (prcm->dpll_speed <= rate)
|
||||
break;
|
||||
}
|
||||
curr_prcm_set = prcm;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2xxx_clkt_vps_late_init - store a copy of the sys_ck rate
|
||||
*
|
||||
* Store a copy of the sys_ck rate for later use by the OMAP2xxx DVFS
|
||||
* code. (The sys_ck rate does not -- or rather, must not -- change
|
||||
* during kernel runtime.) Must be called after we have a valid
|
||||
* sys_ck rate, but before the virt_prcm_set clock rate is
|
||||
* recalculated. No return value.
|
||||
*/
|
||||
void omap2xxx_clkt_vps_late_init(void)
|
||||
{
|
||||
struct clk *c;
|
||||
|
||||
c = clk_get(NULL, "sys_ck");
|
||||
if (IS_ERR(c)) {
|
||||
WARN(1, "could not locate sys_ck\n");
|
||||
} else {
|
||||
sys_ck_rate = clk_get_rate(c);
|
||||
clk_put(c);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,8 +44,10 @@
|
|||
* Program the DPLL M2 divider with the rounded target rate. Returns
|
||||
* -EINVAL upon error, or 0 upon success.
|
||||
*/
|
||||
int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
|
||||
int omap3_core_dpll_m2_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 new_div = 0;
|
||||
u32 unlock_dll = 0;
|
||||
u32 c;
|
||||
|
@ -63,7 +65,7 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
|
|||
return -EINVAL;
|
||||
|
||||
sdrcrate = __clk_get_rate(sdrc_ick_p);
|
||||
clkrate = __clk_get_rate(clk);
|
||||
clkrate = __clk_get_rate(hw->clk);
|
||||
if (rate > clkrate)
|
||||
sdrcrate <<= ((rate / clkrate) >> 1);
|
||||
else
|
||||
|
@ -112,8 +114,6 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
|
|||
sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
|
||||
sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
|
||||
0, 0, 0, 0);
|
||||
clk->rate = rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/bug.h>
|
||||
|
||||
|
@ -58,11 +58,14 @@
|
|||
* the element associated with the supplied parent clock address.
|
||||
* Returns a pointer to the struct clksel on success or NULL on error.
|
||||
*/
|
||||
static const struct clksel *_get_clksel_by_parent(struct clk *clk,
|
||||
static const struct clksel *_get_clksel_by_parent(struct clk_hw_omap *clk,
|
||||
struct clk *src_clk)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
|
||||
if (!src_clk)
|
||||
return NULL;
|
||||
|
||||
for (clks = clk->clksel; clks->parent; clks++)
|
||||
if (clks->parent == src_clk)
|
||||
break; /* Found the requested parent */
|
||||
|
@ -70,71 +73,13 @@ static const struct clksel *_get_clksel_by_parent(struct clk *clk,
|
|||
if (!clks->parent) {
|
||||
/* This indicates a data problem */
|
||||
WARN(1, "clock: %s: could not find parent clock %s in clksel array\n",
|
||||
__clk_get_name(clk), __clk_get_name(src_clk));
|
||||
__clk_get_name(clk->hw.clk), __clk_get_name(src_clk));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return clks;
|
||||
}
|
||||
|
||||
/**
|
||||
* _get_div_and_fieldval() - find the new clksel divisor and field value to use
|
||||
* @src_clk: planned new parent struct clk *
|
||||
* @clk: struct clk * that is being reparented
|
||||
* @field_val: pointer to a u32 to contain the register data for the divisor
|
||||
*
|
||||
* Given an intended new parent struct clk * @src_clk, and the struct
|
||||
* clk * @clk to the clock that is being reparented, find the
|
||||
* appropriate rate divisor for the new clock (returned as the return
|
||||
* value), and the corresponding register bitfield data to program to
|
||||
* reach that divisor (returned in the u32 pointed to by @field_val).
|
||||
* Returns 0 on error, or returns the newly-selected divisor upon
|
||||
* success (in this latter case, the corresponding register bitfield
|
||||
* value is passed back in the variable pointed to by @field_val)
|
||||
*/
|
||||
static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk,
|
||||
u32 *field_val)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr, *max_clkr = NULL;
|
||||
u8 max_div = 0;
|
||||
|
||||
clks = _get_clksel_by_parent(clk, src_clk);
|
||||
if (!clks)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Find the highest divisor (e.g., the one resulting in the
|
||||
* lowest rate) to use as the default. This should avoid
|
||||
* clock rates that are too high for the device. XXX A better
|
||||
* solution here would be to try to determine if there is a
|
||||
* divisor matching the original clock rate before the parent
|
||||
* switch, and if it cannot be found, to fall back to the
|
||||
* highest divisor.
|
||||
*/
|
||||
for (clkr = clks->rates; clkr->div; clkr++) {
|
||||
if (!(clkr->flags & cpu_mask))
|
||||
continue;
|
||||
|
||||
if (clkr->div > max_div) {
|
||||
max_div = clkr->div;
|
||||
max_clkr = clkr;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_div == 0) {
|
||||
/* This indicates an error in the clksel data */
|
||||
WARN(1, "clock: %s: could not find divisor for parent %s\n",
|
||||
__clk_get_name(clk),
|
||||
__clk_get_name(__clk_get_parent(src_clk)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
*field_val = max_clkr->val;
|
||||
|
||||
return max_div;
|
||||
}
|
||||
|
||||
/**
|
||||
* _write_clksel_reg() - program a clock's clksel register in hardware
|
||||
* @clk: struct clk * to program
|
||||
|
@ -148,7 +93,7 @@ static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk,
|
|||
* take into account any time the hardware might take to switch the
|
||||
* clock source.
|
||||
*/
|
||||
static void _write_clksel_reg(struct clk *clk, u32 field_val)
|
||||
static void _write_clksel_reg(struct clk_hw_omap *clk, u32 field_val)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
|
@ -171,13 +116,14 @@ static void _write_clksel_reg(struct clk *clk, u32 field_val)
|
|||
* before calling. Returns 0 on error or returns the actual integer divisor
|
||||
* upon success.
|
||||
*/
|
||||
static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
|
||||
static u32 _clksel_to_divisor(struct clk_hw_omap *clk, u32 field_val)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
struct clk *parent;
|
||||
|
||||
parent = __clk_get_parent(clk);
|
||||
parent = __clk_get_parent(clk->hw.clk);
|
||||
|
||||
clks = _get_clksel_by_parent(clk, parent);
|
||||
if (!clks)
|
||||
return 0;
|
||||
|
@ -193,7 +139,8 @@ static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
|
|||
if (!clkr->div) {
|
||||
/* This indicates a data error */
|
||||
WARN(1, "clock: %s: could not find fieldval %d for parent %s\n",
|
||||
__clk_get_name(clk), field_val, __clk_get_name(parent));
|
||||
__clk_get_name(clk->hw.clk), field_val,
|
||||
__clk_get_name(parent));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -210,7 +157,7 @@ static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
|
|||
* register field value _before_ left-shifting (i.e., LSB is at bit
|
||||
* 0); or returns 0xFFFFFFFF (~0) upon error.
|
||||
*/
|
||||
static u32 _divisor_to_clksel(struct clk *clk, u32 div)
|
||||
static u32 _divisor_to_clksel(struct clk_hw_omap *clk, u32 div)
|
||||
{
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
|
@ -219,7 +166,7 @@ static u32 _divisor_to_clksel(struct clk *clk, u32 div)
|
|||
/* should never happen */
|
||||
WARN_ON(div == 0);
|
||||
|
||||
parent = __clk_get_parent(clk);
|
||||
parent = __clk_get_parent(clk->hw.clk);
|
||||
clks = _get_clksel_by_parent(clk, parent);
|
||||
if (!clks)
|
||||
return ~0;
|
||||
|
@ -234,7 +181,8 @@ static u32 _divisor_to_clksel(struct clk *clk, u32 div)
|
|||
|
||||
if (!clkr->div) {
|
||||
pr_err("clock: %s: could not find divisor %d for parent %s\n",
|
||||
__clk_get_name(clk), div, __clk_get_name(parent));
|
||||
__clk_get_name(clk->hw.clk), div,
|
||||
__clk_get_name(parent));
|
||||
return ~0;
|
||||
}
|
||||
|
||||
|
@ -249,7 +197,7 @@ static u32 _divisor_to_clksel(struct clk *clk, u32 div)
|
|||
* into the hardware, convert it into the actual divisor value, and
|
||||
* return it; or return 0 on error.
|
||||
*/
|
||||
static u32 _read_divisor(struct clk *clk)
|
||||
static u32 _read_divisor(struct clk_hw_omap *clk)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
|
@ -277,7 +225,8 @@ static u32 _read_divisor(struct clk *clk)
|
|||
*
|
||||
* Returns the rounded clock rate or returns 0xffffffff on error.
|
||||
*/
|
||||
u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
|
||||
u32 omap2_clksel_round_rate_div(struct clk_hw_omap *clk,
|
||||
unsigned long target_rate,
|
||||
u32 *new_div)
|
||||
{
|
||||
unsigned long test_rate;
|
||||
|
@ -288,9 +237,9 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
|
|||
unsigned long parent_rate;
|
||||
const char *clk_name;
|
||||
|
||||
parent = __clk_get_parent(clk);
|
||||
parent = __clk_get_parent(clk->hw.clk);
|
||||
clk_name = __clk_get_name(clk->hw.clk);
|
||||
parent_rate = __clk_get_rate(parent);
|
||||
clk_name = __clk_get_name(clk);
|
||||
|
||||
if (!clk->clksel || !clk->clksel_mask)
|
||||
return ~0;
|
||||
|
@ -341,27 +290,35 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
|
|||
*/
|
||||
|
||||
/**
|
||||
* omap2_init_clksel_parent() - set a clksel clk's parent field from the hdwr
|
||||
* @clk: OMAP clock struct ptr to use
|
||||
* omap2_clksel_find_parent_index() - return the array index of the current
|
||||
* hardware parent of @hw
|
||||
* @hw: struct clk_hw * to find the current hardware parent of
|
||||
*
|
||||
* Given a pointer @clk to a source-selectable struct clk, read the
|
||||
* hardware register and determine what its parent is currently set
|
||||
* to. Update @clk's .parent field with the appropriate clk ptr. No
|
||||
* return value.
|
||||
* Given a struct clk_hw pointer @hw to the 'hw' member of a struct
|
||||
* clk_hw_omap record representing a source-selectable hardware clock,
|
||||
* read the hardware register and determine what its parent is
|
||||
* currently set to. Intended to be called only by the common clock
|
||||
* framework struct clk_hw_ops.get_parent function pointer. Return
|
||||
* the array index of this parent clock upon success -- there is no
|
||||
* way to return an error, so if we encounter an error, just WARN()
|
||||
* and pretend that we know that we're doing.
|
||||
*/
|
||||
void omap2_init_clksel_parent(struct clk *clk)
|
||||
u8 omap2_clksel_find_parent_index(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
const struct clksel *clks;
|
||||
const struct clksel_rate *clkr;
|
||||
u32 r, found = 0;
|
||||
struct clk *parent;
|
||||
const char *clk_name;
|
||||
int ret = 0, f = 0;
|
||||
|
||||
if (!clk->clksel || !clk->clksel_mask)
|
||||
return;
|
||||
parent = __clk_get_parent(hw->clk);
|
||||
clk_name = __clk_get_name(hw->clk);
|
||||
|
||||
parent = __clk_get_parent(clk);
|
||||
clk_name = __clk_get_name(clk);
|
||||
/* XXX should be able to return an error */
|
||||
WARN((!clk->clksel || !clk->clksel_mask),
|
||||
"clock: %s: attempt to call on a non-clksel clock", clk_name);
|
||||
|
||||
r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
|
||||
r >>= __ffs(clk->clksel_mask);
|
||||
|
@ -372,27 +329,21 @@ void omap2_init_clksel_parent(struct clk *clk)
|
|||
continue;
|
||||
|
||||
if (clkr->val == r) {
|
||||
if (parent != clks->parent) {
|
||||
pr_debug("clock: %s: inited parent to %s (was %s)\n",
|
||||
clk_name,
|
||||
__clk_get_name(clks->parent),
|
||||
((parent) ?
|
||||
__clk_get_name(parent) :
|
||||
"NULL"));
|
||||
clk_reparent(clk, clks->parent);
|
||||
}
|
||||
found = 1;
|
||||
ret = f;
|
||||
}
|
||||
}
|
||||
f++;
|
||||
}
|
||||
|
||||
/* This indicates a data error */
|
||||
WARN(!found, "clock: %s: init parent: could not find regval %0x\n",
|
||||
clk_name, r);
|
||||
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* omap2_clksel_recalc() - function ptr to pass via struct clk .recalc field
|
||||
* @clk: struct clk *
|
||||
|
@ -402,21 +353,23 @@ void omap2_init_clksel_parent(struct clk *clk)
|
|||
* function. Returns the clock's current rate, based on its parent's rate
|
||||
* and its current divisor setting in the hardware.
|
||||
*/
|
||||
unsigned long omap2_clksel_recalc(struct clk *clk)
|
||||
unsigned long omap2_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate)
|
||||
{
|
||||
unsigned long rate;
|
||||
u32 div = 0;
|
||||
struct clk *parent;
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
|
||||
if (!parent_rate)
|
||||
return 0;
|
||||
|
||||
div = _read_divisor(clk);
|
||||
if (div == 0)
|
||||
return __clk_get_rate(clk);
|
||||
if (!div)
|
||||
rate = parent_rate;
|
||||
else
|
||||
rate = parent_rate / div;
|
||||
|
||||
parent = __clk_get_parent(clk);
|
||||
rate = __clk_get_rate(parent) / div;
|
||||
|
||||
pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n",
|
||||
__clk_get_name(clk), rate, div);
|
||||
pr_debug("%s: recalc'd %s's rate to %lu (div %d)\n", __func__,
|
||||
__clk_get_name(hw->clk), rate, div);
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
@ -432,8 +385,10 @@ unsigned long omap2_clksel_recalc(struct clk *clk)
|
|||
*
|
||||
* Returns the rounded clock rate or returns 0xffffffff on error.
|
||||
*/
|
||||
long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
|
||||
long omap2_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 new_div;
|
||||
|
||||
return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
|
||||
|
@ -454,8 +409,10 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
|
|||
* is changed, they will all be affected without any notification.
|
||||
* Returns -EINVAL upon error, or 0 upon success.
|
||||
*/
|
||||
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
|
||||
int omap2_clksel_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 field_val, validrate, new_div = 0;
|
||||
|
||||
if (!clk->clksel || !clk->clksel_mask)
|
||||
|
@ -471,10 +428,8 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
|
|||
|
||||
_write_clksel_reg(clk, field_val);
|
||||
|
||||
clk->rate = __clk_get_rate(__clk_get_parent(clk)) / new_div;
|
||||
|
||||
pr_debug("clock: %s: set rate to %ld\n", __clk_get_name(clk),
|
||||
__clk_get_rate(clk));
|
||||
pr_debug("clock: %s: set rate to %ld\n", __clk_get_name(hw->clk),
|
||||
__clk_get_rate(hw->clk));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -499,32 +454,13 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
|
|||
* affected without any notification. Returns -EINVAL upon error, or
|
||||
* 0 upon success.
|
||||
*/
|
||||
int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent)
|
||||
int omap2_clksel_set_parent(struct clk_hw *hw, u8 field_val)
|
||||
{
|
||||
u32 field_val = 0;
|
||||
u32 parent_div;
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
|
||||
if (!clk->clksel || !clk->clksel_mask)
|
||||
return -EINVAL;
|
||||
|
||||
parent_div = _get_div_and_fieldval(new_parent, clk, &field_val);
|
||||
if (!parent_div)
|
||||
return -EINVAL;
|
||||
|
||||
_write_clksel_reg(clk, field_val);
|
||||
|
||||
clk_reparent(clk, new_parent);
|
||||
|
||||
/* CLKSEL clocks follow their parents' rates, divided by a divisor */
|
||||
clk->rate = __clk_get_rate(new_parent);
|
||||
|
||||
if (parent_div > 0)
|
||||
__clk_get_rate(clk) /= parent_div;
|
||||
|
||||
pr_debug("clock: %s: set parent to %s (new rate %ld)\n",
|
||||
__clk_get_name(clk),
|
||||
__clk_get_name(__clk_get_parent(clk)),
|
||||
__clk_get_rate(clk));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/div64.h>
|
||||
|
@ -76,7 +76,7 @@
|
|||
* (assuming that it is counting N upwards), or -2 if the enclosing loop
|
||||
* should skip to the next iteration (again assuming N is increasing).
|
||||
*/
|
||||
static int _dpll_test_fint(struct clk *clk, u8 n)
|
||||
static int _dpll_test_fint(struct clk_hw_omap *clk, u8 n)
|
||||
{
|
||||
struct dpll_data *dd;
|
||||
long fint, fint_min, fint_max;
|
||||
|
@ -85,7 +85,7 @@ static int _dpll_test_fint(struct clk *clk, u8 n)
|
|||
dd = clk->dpll_data;
|
||||
|
||||
/* DPLL divider must result in a valid jitter correction val */
|
||||
fint = __clk_get_rate(__clk_get_parent(clk)) / n;
|
||||
fint = __clk_get_rate(__clk_get_parent(clk->hw.clk)) / n;
|
||||
|
||||
if (cpu_is_omap24xx()) {
|
||||
/* Should not be called for OMAP2, so warn if it is called */
|
||||
|
@ -186,15 +186,15 @@ static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
|
|||
}
|
||||
|
||||
/* Public functions */
|
||||
|
||||
void omap2_init_dpll_parent(struct clk *clk)
|
||||
u8 omap2_init_dpll_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 v;
|
||||
struct dpll_data *dd;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
if (!dd)
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
v = __raw_readl(dd->control_reg);
|
||||
v &= dd->enable_mask;
|
||||
|
@ -204,18 +204,18 @@ void omap2_init_dpll_parent(struct clk *clk)
|
|||
if (cpu_is_omap24xx()) {
|
||||
if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP2XXX_EN_DPLL_FRBYPASS)
|
||||
clk_reparent(clk, dd->clk_bypass);
|
||||
return 1;
|
||||
} else if (cpu_is_omap34xx()) {
|
||||
if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP3XXX_EN_DPLL_FRBYPASS)
|
||||
clk_reparent(clk, dd->clk_bypass);
|
||||
return 1;
|
||||
} else if (soc_is_am33xx() || cpu_is_omap44xx()) {
|
||||
if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
|
||||
v == OMAP4XXX_EN_DPLL_FRBYPASS ||
|
||||
v == OMAP4XXX_EN_DPLL_MNBYPASS)
|
||||
clk_reparent(clk, dd->clk_bypass);
|
||||
return 1;
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,7 +232,7 @@ void omap2_init_dpll_parent(struct clk *clk)
|
|||
* locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
|
||||
* if the clock @clk is not a DPLL.
|
||||
*/
|
||||
u32 omap2_get_dpll_rate(struct clk *clk)
|
||||
unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk)
|
||||
{
|
||||
long long dpll_clk;
|
||||
u32 dpll_mult, dpll_div, v;
|
||||
|
@ -288,8 +288,10 @@ u32 omap2_get_dpll_rate(struct clk *clk)
|
|||
* (expensive) function again. Returns ~0 if the target rate cannot
|
||||
* be rounded, or the rounded rate upon success.
|
||||
*/
|
||||
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
|
||||
long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
int m, n, r, scaled_max_m;
|
||||
unsigned long scaled_rt_rp;
|
||||
unsigned long new_rate = 0;
|
||||
|
@ -303,7 +305,7 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
|
|||
dd = clk->dpll_data;
|
||||
|
||||
ref_rate = __clk_get_rate(dd->clk_ref);
|
||||
clk_name = __clk_get_name(clk);
|
||||
clk_name = __clk_get_name(hw->clk);
|
||||
pr_debug("clock: %s: starting DPLL round_rate, target rate %ld\n",
|
||||
clk_name, target_rate);
|
||||
|
||||
|
|
|
@ -11,10 +11,9 @@
|
|||
#undef DEBUG
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/prcm.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
|
@ -24,7 +23,7 @@
|
|||
/* Private functions */
|
||||
|
||||
/* XXX */
|
||||
void omap2_clkt_iclk_allow_idle(struct clk *clk)
|
||||
void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
u32 v, r;
|
||||
|
||||
|
@ -36,7 +35,7 @@ void omap2_clkt_iclk_allow_idle(struct clk *clk)
|
|||
}
|
||||
|
||||
/* XXX */
|
||||
void omap2_clkt_iclk_deny_idle(struct clk *clk)
|
||||
void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
u32 v, r;
|
||||
|
||||
|
@ -49,33 +48,17 @@ void omap2_clkt_iclk_deny_idle(struct clk *clk)
|
|||
|
||||
/* Public data */
|
||||
|
||||
const struct clkops clkops_omap2_iclk_dflt_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
const struct clk_hw_omap_ops clkhwops_iclk = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
};
|
||||
|
||||
const struct clk_hw_omap_ops clkhwops_iclk_wait = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
.find_idlest = omap2_clk_dflt_find_idlest,
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap2_iclk_dflt = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap2_iclk_idle_only = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap2_mdmclk_dflt_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
.find_idlest = omap2_clk_dflt_find_idlest,
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -20,6 +20,7 @@
|
|||
#include <linux/list.h>
|
||||
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
struct omap_clk {
|
||||
u16 cpu;
|
||||
|
@ -52,43 +53,84 @@ struct omap_clk {
|
|||
#define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS)
|
||||
#define CK_3XXX (CK_34XX | CK_AM35XX | CK_36XX)
|
||||
|
||||
struct module;
|
||||
struct clk;
|
||||
struct clockdomain;
|
||||
#define to_clk_hw_omap(_hw) container_of(_hw, struct clk_hw_omap, hw)
|
||||
|
||||
/* Temporary, needed during the common clock framework conversion */
|
||||
#define __clk_get_name(clk) (clk->name)
|
||||
#define __clk_get_parent(clk) (clk->parent)
|
||||
#define __clk_get_rate(clk) (clk->rate)
|
||||
#define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name) \
|
||||
static struct clk _name = { \
|
||||
.name = #_name, \
|
||||
.hw = &_name##_hw.hw, \
|
||||
.parent_names = _parent_array_name, \
|
||||
.num_parents = ARRAY_SIZE(_parent_array_name), \
|
||||
.ops = &_clkops_name, \
|
||||
};
|
||||
|
||||
/**
|
||||
* struct clkops - some clock function pointers
|
||||
* @enable: fn ptr that enables the current clock in hardware
|
||||
* @disable: fn ptr that enables the current clock in hardware
|
||||
* @find_idlest: function returning the IDLEST register for the clock's IP blk
|
||||
* @find_companion: function returning the "companion" clk reg for the clock
|
||||
* @allow_idle: fn ptr that enables autoidle for the current clock in hardware
|
||||
* @deny_idle: fn ptr that disables autoidle for the current clock in hardware
|
||||
*
|
||||
* A "companion" clk is an accompanying clock to the one being queried
|
||||
* that must be enabled for the IP module connected to the clock to
|
||||
* become accessible by the hardware. Neither @find_idlest nor
|
||||
* @find_companion should be needed; that information is IP
|
||||
* block-specific; the hwmod code has been created to handle this, but
|
||||
* until hwmod data is ready and drivers have been converted to use PM
|
||||
* runtime calls in place of clk_enable()/clk_disable(), @find_idlest and
|
||||
* @find_companion must, unfortunately, remain.
|
||||
*/
|
||||
struct clkops {
|
||||
int (*enable)(struct clk *);
|
||||
void (*disable)(struct clk *);
|
||||
void (*find_idlest)(struct clk *, void __iomem **,
|
||||
u8 *, u8 *);
|
||||
void (*find_companion)(struct clk *, void __iomem **,
|
||||
u8 *);
|
||||
void (*allow_idle)(struct clk *);
|
||||
void (*deny_idle)(struct clk *);
|
||||
};
|
||||
#define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name) \
|
||||
static struct clk_hw_omap _name##_hw = { \
|
||||
.hw = { \
|
||||
.clk = &_name, \
|
||||
}, \
|
||||
.clkdm_name = _clkdm_name, \
|
||||
};
|
||||
|
||||
#define DEFINE_CLK_OMAP_MUX(_name, _clkdm_name, _clksel, \
|
||||
_clksel_reg, _clksel_mask, \
|
||||
_parent_names, _ops) \
|
||||
static struct clk _name; \
|
||||
static struct clk_hw_omap _name##_hw = { \
|
||||
.hw = { \
|
||||
.clk = &_name, \
|
||||
}, \
|
||||
.clksel = _clksel, \
|
||||
.clksel_reg = _clksel_reg, \
|
||||
.clksel_mask = _clksel_mask, \
|
||||
.clkdm_name = _clkdm_name, \
|
||||
}; \
|
||||
DEFINE_STRUCT_CLK(_name, _parent_names, _ops);
|
||||
|
||||
#define DEFINE_CLK_OMAP_MUX_GATE(_name, _clkdm_name, _clksel, \
|
||||
_clksel_reg, _clksel_mask, \
|
||||
_enable_reg, _enable_bit, \
|
||||
_hwops, _parent_names, _ops) \
|
||||
static struct clk _name; \
|
||||
static struct clk_hw_omap _name##_hw = { \
|
||||
.hw = { \
|
||||
.clk = &_name, \
|
||||
}, \
|
||||
.ops = _hwops, \
|
||||
.enable_reg = _enable_reg, \
|
||||
.enable_bit = _enable_bit, \
|
||||
.clksel = _clksel, \
|
||||
.clksel_reg = _clksel_reg, \
|
||||
.clksel_mask = _clksel_mask, \
|
||||
.clkdm_name = _clkdm_name, \
|
||||
}; \
|
||||
DEFINE_STRUCT_CLK(_name, _parent_names, _ops);
|
||||
|
||||
#define DEFINE_CLK_OMAP_HSDIVIDER(_name, _parent_name, \
|
||||
_parent_ptr, _flags, \
|
||||
_clksel_reg, _clksel_mask) \
|
||||
static const struct clksel _name##_div[] = { \
|
||||
{ \
|
||||
.parent = _parent_ptr, \
|
||||
.rates = div31_1to31_rates \
|
||||
}, \
|
||||
{ .parent = NULL }, \
|
||||
}; \
|
||||
static struct clk _name; \
|
||||
static const char *_name##_parent_names[] = { \
|
||||
_parent_name, \
|
||||
}; \
|
||||
static struct clk_hw_omap _name##_hw = { \
|
||||
.hw = { \
|
||||
.clk = &_name, \
|
||||
}, \
|
||||
.clksel = _name##_div, \
|
||||
.clksel_reg = _clksel_reg, \
|
||||
.clksel_mask = _clksel_mask, \
|
||||
.ops = &clkhwops_omap4_dpllmx, \
|
||||
}; \
|
||||
DEFINE_STRUCT_CLK(_name, _name##_parent_names, omap_hsdivider_ops);
|
||||
|
||||
/* struct clksel_rate.flags possibilities */
|
||||
#define RATE_IN_242X (1 << 0)
|
||||
|
@ -229,22 +271,10 @@ struct dpll_data {
|
|||
#define CLOCK_CLKOUTX2 (1 << 5)
|
||||
|
||||
/**
|
||||
* struct clk - OMAP struct clk
|
||||
* struct clk_hw_omap - OMAP struct clk
|
||||
* @node: list_head connecting this clock into the full clock list
|
||||
* @ops: struct clkops * for this clock
|
||||
* @name: the name of the clock in the hardware (used in hwmod data and debug)
|
||||
* @parent: pointer to this clock's parent struct clk
|
||||
* @children: list_head connecting to the child clks' @sibling list_heads
|
||||
* @sibling: list_head connecting this clk to its parent clk's @children
|
||||
* @rate: current clock rate
|
||||
* @enable_reg: register to write to enable the clock (see @enable_bit)
|
||||
* @recalc: fn ptr that returns the clock's current rate
|
||||
* @set_rate: fn ptr that can change the clock's current rate
|
||||
* @round_rate: fn ptr that can round the clock's current rate
|
||||
* @init: fn ptr to do clock-specific initialization
|
||||
* @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
|
||||
* @usecount: number of users that have requested this clock to be enabled
|
||||
* @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div
|
||||
* @flags: see "struct clk.flags possibilities" above
|
||||
* @clksel_reg: for clksel clks, register va containing src/divisor select
|
||||
* @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
|
||||
|
@ -258,39 +288,17 @@ struct dpll_data {
|
|||
* XXX @rate_offset, @src_offset should probably be removed and OMAP1
|
||||
* clock code converted to use clksel.
|
||||
*
|
||||
* XXX @usecount is poorly named. It should be "enable_count" or
|
||||
* something similar. "users" in the description refers to kernel
|
||||
* code (core code or drivers) that have called clk_enable() and not
|
||||
* yet called clk_disable(); the usecount of parent clocks is also
|
||||
* incremented by the clock code when clk_enable() is called on child
|
||||
* clocks and decremented by the clock code when clk_disable() is
|
||||
* called on child clocks.
|
||||
*
|
||||
* XXX @clkdm, @usecount, @children, @sibling should be marked for
|
||||
* internal use only.
|
||||
*
|
||||
* @children and @sibling are used to optimize parent-to-child clock
|
||||
* tree traversals. (child-to-parent traversals use @parent.)
|
||||
*
|
||||
* XXX The notion of the clock's current rate probably needs to be
|
||||
* separated from the clock's target rate.
|
||||
*/
|
||||
struct clk {
|
||||
|
||||
struct clk_hw_omap_ops;
|
||||
|
||||
struct clk_hw_omap {
|
||||
struct clk_hw hw;
|
||||
struct list_head node;
|
||||
const struct clkops *ops;
|
||||
const char *name;
|
||||
struct clk *parent;
|
||||
struct list_head children;
|
||||
struct list_head sibling; /* node for children */
|
||||
unsigned long rate;
|
||||
void __iomem *enable_reg;
|
||||
unsigned long (*recalc)(struct clk *);
|
||||
int (*set_rate)(struct clk *, unsigned long);
|
||||
long (*round_rate)(struct clk *, unsigned long);
|
||||
void (*init)(struct clk *);
|
||||
u8 enable_bit;
|
||||
s8 usecount;
|
||||
unsigned long fixed_rate;
|
||||
u8 fixed_div;
|
||||
void __iomem *enable_reg;
|
||||
u8 enable_bit;
|
||||
u8 flags;
|
||||
void __iomem *clksel_reg;
|
||||
u32 clksel_mask;
|
||||
|
@ -298,42 +306,22 @@ struct clk {
|
|||
struct dpll_data *dpll_data;
|
||||
const char *clkdm_name;
|
||||
struct clockdomain *clkdm;
|
||||
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
|
||||
struct dentry *dent; /* For visible tree hierarchy */
|
||||
#endif
|
||||
const struct clk_hw_omap_ops *ops;
|
||||
};
|
||||
|
||||
struct clk_functions {
|
||||
int (*clk_enable)(struct clk *clk);
|
||||
void (*clk_disable)(struct clk *clk);
|
||||
long (*clk_round_rate)(struct clk *clk, unsigned long rate);
|
||||
int (*clk_set_rate)(struct clk *clk, unsigned long rate);
|
||||
int (*clk_set_parent)(struct clk *clk, struct clk *parent);
|
||||
void (*clk_allow_idle)(struct clk *clk);
|
||||
void (*clk_deny_idle)(struct clk *clk);
|
||||
void (*clk_disable_unused)(struct clk *clk);
|
||||
struct clk_hw_omap_ops {
|
||||
void (*find_idlest)(struct clk_hw_omap *oclk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit, u8 *idlest_val);
|
||||
void (*find_companion)(struct clk_hw_omap *oclk,
|
||||
void __iomem **other_reg,
|
||||
u8 *other_bit);
|
||||
void (*allow_idle)(struct clk_hw_omap *oclk);
|
||||
void (*deny_idle)(struct clk_hw_omap *oclk);
|
||||
};
|
||||
|
||||
extern int mpurate;
|
||||
|
||||
extern int clk_init(struct clk_functions *custom_clocks);
|
||||
extern void clk_preinit(struct clk *clk);
|
||||
extern int clk_register(struct clk *clk);
|
||||
extern void clk_reparent(struct clk *child, struct clk *parent);
|
||||
extern void clk_unregister(struct clk *clk);
|
||||
extern void propagate_rate(struct clk *clk);
|
||||
extern void recalculate_root_clocks(void);
|
||||
extern unsigned long followparent_recalc(struct clk *clk);
|
||||
extern void clk_enable_init_clocks(void);
|
||||
unsigned long omap_fixed_divisor_recalc(struct clk *clk);
|
||||
extern struct clk *omap_clk_get_by_name(const char *name);
|
||||
extern int omap_clk_enable_autoidle_all(void);
|
||||
extern int omap_clk_disable_autoidle_all(void);
|
||||
|
||||
extern const struct clkops clkops_null;
|
||||
|
||||
extern struct clk dummy_ck;
|
||||
|
||||
unsigned long omap_fixed_divisor_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
|
||||
/* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
|
||||
#define CORE_CLK_SRC_32K 0x0
|
||||
|
@ -364,84 +352,62 @@ extern struct clk dummy_ck;
|
|||
/* DPLL Type and DCO Selection Flags */
|
||||
#define DPLL_J_TYPE 0x1
|
||||
|
||||
int omap2_clk_enable(struct clk *clk);
|
||||
void omap2_clk_disable(struct clk *clk);
|
||||
long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
|
||||
int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
|
||||
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
|
||||
unsigned long omap3_dpll_recalc(struct clk *clk);
|
||||
unsigned long omap3_clkoutx2_recalc(struct clk *clk);
|
||||
void omap3_dpll_allow_idle(struct clk *clk);
|
||||
void omap3_dpll_deny_idle(struct clk *clk);
|
||||
u32 omap3_dpll_autoidle_read(struct clk *clk);
|
||||
int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap3_noncore_dpll_enable(struct clk *clk);
|
||||
void omap3_noncore_dpll_disable(struct clk *clk);
|
||||
int omap4_dpllmx_gatectrl_read(struct clk *clk);
|
||||
void omap4_dpllmx_allow_gatectrl(struct clk *clk);
|
||||
void omap4_dpllmx_deny_gatectrl(struct clk *clk);
|
||||
long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate);
|
||||
unsigned long omap4_dpll_regm4xen_recalc(struct clk *clk);
|
||||
long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
|
||||
unsigned long *parent_rate);
|
||||
unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate);
|
||||
int omap3_noncore_dpll_enable(struct clk_hw *hw);
|
||||
void omap3_noncore_dpll_disable(struct clk_hw *hw);
|
||||
int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk);
|
||||
void omap3_dpll_allow_idle(struct clk_hw_omap *clk);
|
||||
void omap3_dpll_deny_idle(struct clk_hw_omap *clk);
|
||||
unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk);
|
||||
void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk);
|
||||
void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk);
|
||||
unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
|
||||
unsigned long target_rate,
|
||||
unsigned long *parent_rate);
|
||||
|
||||
#ifdef CONFIG_OMAP_RESET_CLOCKS
|
||||
void omap2_clk_disable_unused(struct clk *clk);
|
||||
#else
|
||||
#define omap2_clk_disable_unused NULL
|
||||
#endif
|
||||
|
||||
void omap2_init_clk_clkdm(struct clk *clk);
|
||||
void omap2_init_clk_clkdm(struct clk_hw *clk);
|
||||
void __init omap2_clk_disable_clkdm_control(void);
|
||||
|
||||
/* clkt_clksel.c public functions */
|
||||
u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
|
||||
u32 omap2_clksel_round_rate_div(struct clk_hw_omap *clk,
|
||||
unsigned long target_rate,
|
||||
u32 *new_div);
|
||||
void omap2_init_clksel_parent(struct clk *clk);
|
||||
unsigned long omap2_clksel_recalc(struct clk *clk);
|
||||
long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate);
|
||||
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent);
|
||||
u8 omap2_clksel_find_parent_index(struct clk_hw *hw);
|
||||
unsigned long omap2_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate);
|
||||
long omap2_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate,
|
||||
unsigned long *parent_rate);
|
||||
int omap2_clksel_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
int omap2_clksel_set_parent(struct clk_hw *hw, u8 field_val);
|
||||
|
||||
/* clkt_iclk.c public functions */
|
||||
extern void omap2_clkt_iclk_allow_idle(struct clk *clk);
|
||||
extern void omap2_clkt_iclk_deny_idle(struct clk *clk);
|
||||
extern void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk);
|
||||
extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk);
|
||||
|
||||
u32 omap2_get_dpll_rate(struct clk *clk);
|
||||
void omap2_init_dpll_parent(struct clk *clk);
|
||||
u8 omap2_init_dpll_parent(struct clk_hw *hw);
|
||||
unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk);
|
||||
|
||||
int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
|
||||
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP2
|
||||
void omap2xxx_clk_prepare_for_reboot(void);
|
||||
#else
|
||||
static inline void omap2xxx_clk_prepare_for_reboot(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP3
|
||||
void omap3_clk_prepare_for_reboot(void);
|
||||
#else
|
||||
static inline void omap3_clk_prepare_for_reboot(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP4
|
||||
void omap4_clk_prepare_for_reboot(void);
|
||||
#else
|
||||
static inline void omap4_clk_prepare_for_reboot(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
int omap2_dflt_clk_enable(struct clk *clk);
|
||||
void omap2_dflt_clk_disable(struct clk *clk);
|
||||
void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
|
||||
int omap2_dflt_clk_enable(struct clk_hw *hw);
|
||||
void omap2_dflt_clk_disable(struct clk_hw *hw);
|
||||
int omap2_dflt_clk_is_enabled(struct clk_hw *hw);
|
||||
void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk,
|
||||
void __iomem **other_reg,
|
||||
u8 *other_bit);
|
||||
void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
|
||||
void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit, u8 *idlest_val);
|
||||
void omap2_init_clk_hw_omap_clocks(struct clk *clk);
|
||||
int omap2_clk_enable_autoidle_all(void);
|
||||
int omap2_clk_disable_autoidle_all(void);
|
||||
void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks);
|
||||
int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name);
|
||||
void omap2_clk_print_new_rates(const char *hfclkin_ck_name,
|
||||
const char *core_ck_name,
|
||||
|
@ -454,34 +420,43 @@ extern const struct clkops clkops_dummy;
|
|||
extern const struct clkops clkops_omap2_dflt;
|
||||
|
||||
extern struct clk_functions omap2_clk_functions;
|
||||
extern struct clk *vclk, *sclk;
|
||||
|
||||
extern const struct clksel_rate gpt_32k_rates[];
|
||||
extern const struct clksel_rate gpt_sys_rates[];
|
||||
extern const struct clksel_rate gfx_l3_rates[];
|
||||
extern const struct clksel_rate dsp_ick_rates[];
|
||||
extern struct clk dummy_ck;
|
||||
|
||||
extern const struct clkops clkops_omap2_iclk_dflt_wait;
|
||||
extern const struct clkops clkops_omap2_iclk_dflt;
|
||||
extern const struct clkops clkops_omap2_iclk_idle_only;
|
||||
extern const struct clkops clkops_omap2_mdmclk_dflt_wait;
|
||||
extern const struct clkops clkops_omap2xxx_dpll_ops;
|
||||
extern const struct clkops clkops_omap3_noncore_dpll_ops;
|
||||
extern const struct clkops clkops_omap3_core_dpll_ops;
|
||||
extern const struct clkops clkops_omap4_dpllmx_ops;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3_dpll;
|
||||
extern const struct clk_hw_omap_ops clkhwops_iclk_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap4_dpllmx;
|
||||
extern const struct clk_hw_omap_ops clkhwops_iclk;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait;
|
||||
extern const struct clk_hw_omap_ops clkhwops_apll54;
|
||||
extern const struct clk_hw_omap_ops clkhwops_apll96;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll;
|
||||
extern const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait;
|
||||
|
||||
/* clksel_rate blocks shared between OMAP44xx and AM33xx */
|
||||
extern const struct clksel_rate div_1_0_rates[];
|
||||
extern const struct clksel_rate div3_1to4_rates[];
|
||||
extern const struct clksel_rate div_1_1_rates[];
|
||||
extern const struct clksel_rate div_1_2_rates[];
|
||||
extern const struct clksel_rate div_1_3_rates[];
|
||||
extern const struct clksel_rate div_1_4_rates[];
|
||||
extern const struct clksel_rate div31_1to31_rates[];
|
||||
|
||||
/* clocks shared between various OMAP SoCs */
|
||||
extern struct clk virt_19200000_ck;
|
||||
extern struct clk virt_26000000_ck;
|
||||
|
||||
extern int am33xx_clk_init(void);
|
||||
|
||||
extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
|
||||
extern void omap2_clkops_disable_clkdm(struct clk_hw *hw);
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -25,7 +25,7 @@
|
|||
#include "iomap.h"
|
||||
#include "clock.h"
|
||||
#include "clock2xxx.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
#include "cm2xxx.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
|
||||
/**
|
||||
|
@ -40,7 +40,7 @@
|
|||
* passes back the correct CM_IDLEST register address for I2CHS
|
||||
* modules. No return value.
|
||||
*/
|
||||
static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
|
||||
static void omap2430_clk_i2chs_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
|
@ -51,9 +51,7 @@ static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
|
|||
}
|
||||
|
||||
/* 2430 I2CHS has non-standard IDLEST register */
|
||||
const struct clkops clkops_omap2430_i2chs_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
const struct clk_hw_omap_ops clkhwops_omap2430_i2chs_wait = {
|
||||
.find_idlest = omap2430_clk_i2chs_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,26 +28,11 @@
|
|||
#include "cm.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
|
||||
struct clk *vclk, *sclk, *dclk;
|
||||
|
||||
struct clk_hw *dclk_hw;
|
||||
/*
|
||||
* Omap24xx specific clock functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Set clocks for bypass mode for reboot to work.
|
||||
*/
|
||||
void omap2xxx_clk_prepare_for_reboot(void)
|
||||
{
|
||||
u32 rate;
|
||||
|
||||
if (vclk == NULL || sclk == NULL)
|
||||
return;
|
||||
|
||||
rate = clk_get_rate(sclk);
|
||||
clk_set_rate(vclk, rate);
|
||||
}
|
||||
|
||||
/*
|
||||
* Switch the MPU rate if specified on cmdline. We cannot do this
|
||||
* early until cmdline is parsed. XXX This should be removed from the
|
||||
|
|
|
@ -8,17 +8,34 @@
|
|||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H
|
||||
|
||||
unsigned long omap2_table_mpu_recalc(struct clk *clk);
|
||||
int omap2_select_table_rate(struct clk *clk, unsigned long rate);
|
||||
long omap2_round_to_table_rate(struct clk *clk, unsigned long rate);
|
||||
unsigned long omap2xxx_sys_clk_recalc(struct clk *clk);
|
||||
unsigned long omap2_osc_clk_recalc(struct clk *clk);
|
||||
unsigned long omap2_dpllcore_recalc(struct clk *clk);
|
||||
int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
|
||||
unsigned long omap2xxx_clk_get_core_rate(struct clk *clk);
|
||||
#include <linux/clk-provider.h>
|
||||
#include "clock.h"
|
||||
|
||||
unsigned long omap2_table_mpu_recalc(struct clk_hw *clk,
|
||||
unsigned long parent_rate);
|
||||
int omap2_select_table_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
long omap2_round_to_table_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate);
|
||||
unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk,
|
||||
unsigned long parent_rate);
|
||||
unsigned long omap2_osc_clk_recalc(struct clk_hw *clk,
|
||||
unsigned long parent_rate);
|
||||
unsigned long omap2_dpllcore_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw);
|
||||
unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
unsigned long omap2xxx_clk_get_core_rate(void);
|
||||
u32 omap2xxx_get_apll_clkin(void);
|
||||
u32 omap2xxx_get_sysclkdiv(void);
|
||||
void omap2xxx_clk_prepare_for_reboot(void);
|
||||
void omap2xxx_clkt_vps_check_bootloader_rates(void);
|
||||
void omap2xxx_clkt_vps_late_init(void);
|
||||
|
||||
#ifdef CONFIG_SOC_OMAP2420
|
||||
int omap2420_clk_init(void);
|
||||
|
@ -32,13 +49,14 @@ int omap2430_clk_init(void);
|
|||
#define omap2430_clk_init() do { } while(0)
|
||||
#endif
|
||||
|
||||
extern void __iomem *prcm_clksrc_ctrl, *cm_idlest_pll;
|
||||
extern void __iomem *prcm_clksrc_ctrl;
|
||||
|
||||
extern struct clk *dclk;
|
||||
|
||||
extern const struct clkops clkops_omap2430_i2chs_wait;
|
||||
extern const struct clkops clkops_oscck;
|
||||
extern const struct clkops clkops_apll96;
|
||||
extern const struct clkops clkops_apll54;
|
||||
extern struct clk_hw *dclk_hw;
|
||||
int omap2_enable_osc_ck(struct clk_hw *hw);
|
||||
void omap2_disable_osc_ck(struct clk_hw *hw);
|
||||
int omap2_clk_apll96_enable(struct clk_hw *hw);
|
||||
int omap2_clk_apll54_enable(struct clk_hw *hw);
|
||||
void omap2_clk_apll96_disable(struct clk_hw *hw);
|
||||
void omap2_clk_apll54_disable(struct clk_hw *hw);
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "clock.h"
|
||||
#include "clock34xx.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
#include "cm3xxx.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
|
||||
/**
|
||||
|
@ -37,7 +37,7 @@
|
|||
* from the CM_{I,F}CLKEN bit. Pass back the correct info via
|
||||
* @idlest_reg and @idlest_bit. No return value.
|
||||
*/
|
||||
static void omap3430es2_clk_ssi_find_idlest(struct clk *clk,
|
||||
static void omap3430es2_clk_ssi_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
|
@ -49,21 +49,16 @@ static void omap3430es2_clk_ssi_find_idlest(struct clk *clk,
|
|||
*idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT;
|
||||
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap3430es2_ssi_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait = {
|
||||
.find_idlest = omap3430es2_clk_ssi_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap3430es2_iclk_ssi_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_idlest = omap3430es2_clk_ssi_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
.find_idlest = omap3430es2_clk_ssi_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -80,7 +75,7 @@ const struct clkops clkops_omap3430es2_iclk_ssi_wait = {
|
|||
* default find_idlest code assumes that they are at the same
|
||||
* position.) No return value.
|
||||
*/
|
||||
static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
|
||||
static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
|
@ -94,20 +89,16 @@ static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
|
|||
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait = {
|
||||
.find_idlest = omap3430es2_clk_dss_usbhost_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap3430es2_iclk_dss_usbhost_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_idlest = omap3430es2_clk_dss_usbhost_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
.find_idlest = omap3430es2_clk_dss_usbhost_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -121,7 +112,7 @@ const struct clkops clkops_omap3430es2_iclk_dss_usbhost_wait = {
|
|||
* shift from the CM_{I,F}CLKEN bit. Pass back the correct info via
|
||||
* @idlest_reg and @idlest_bit. No return value.
|
||||
*/
|
||||
static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk,
|
||||
static void omap3430es2_clk_hsotgusb_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
|
@ -134,18 +125,14 @@ static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk,
|
|||
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap3430es2_hsotgusb_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_idlest = omap3430es2_clk_hsotgusb_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap3430es2_iclk_hsotgusb_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_idlest = omap3430es2_clk_hsotgusb_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
.find_idlest = omap3430es2_clk_hsotgusb_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait = {
|
||||
.find_idlest = omap3430es2_clk_hsotgusb_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "clock.h"
|
||||
#include "clock3517.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
#include "cm3xxx.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
|
||||
/*
|
||||
|
@ -47,7 +47,7 @@
|
|||
* in the enable register itsel at a bit offset of 4 from the enable
|
||||
* bit. A value of 1 indicates that clock is enabled.
|
||||
*/
|
||||
static void am35xx_clk_find_idlest(struct clk *clk,
|
||||
static void am35xx_clk_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
|
@ -71,8 +71,9 @@ static void am35xx_clk_find_idlest(struct clk *clk,
|
|||
* associate this type of code with per-module data structures to
|
||||
* avoid this issue, and remove the casts. No return value.
|
||||
*/
|
||||
static void am35xx_clk_find_companion(struct clk *clk, void __iomem **other_reg,
|
||||
u8 *other_bit)
|
||||
static void am35xx_clk_find_companion(struct clk_hw_omap *clk,
|
||||
void __iomem **other_reg,
|
||||
u8 *other_bit)
|
||||
{
|
||||
*other_reg = (__force void __iomem *)(clk->enable_reg);
|
||||
if (clk->enable_bit & AM35XX_IPSS_ICK_MASK)
|
||||
|
@ -80,10 +81,7 @@ static void am35xx_clk_find_companion(struct clk *clk, void __iomem **other_reg,
|
|||
else
|
||||
*other_bit = clk->enable_bit - AM35XX_IPSS_ICK_FCK_OFFSET;
|
||||
}
|
||||
|
||||
const struct clkops clkops_am35xx_ipss_module_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait = {
|
||||
.find_idlest = am35xx_clk_find_idlest,
|
||||
.find_companion = am35xx_clk_find_companion,
|
||||
};
|
||||
|
@ -99,7 +97,7 @@ const struct clkops clkops_am35xx_ipss_module_wait = {
|
|||
* CM_{I,F}CLKEN bit. Pass back the correct info via @idlest_reg
|
||||
* and @idlest_bit. No return value.
|
||||
*/
|
||||
static void am35xx_clk_ipss_find_idlest(struct clk *clk,
|
||||
static void am35xx_clk_ipss_find_idlest(struct clk_hw_omap *clk,
|
||||
void __iomem **idlest_reg,
|
||||
u8 *idlest_bit,
|
||||
u8 *idlest_val)
|
||||
|
@ -112,13 +110,9 @@ static void am35xx_clk_ipss_find_idlest(struct clk *clk,
|
|||
*idlest_val = OMAP34XX_CM_IDLEST_VAL;
|
||||
}
|
||||
|
||||
const struct clkops clkops_am35xx_ipss_wait = {
|
||||
.enable = omap2_dflt_clk_enable,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_idlest = am35xx_clk_ipss_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait = {
|
||||
.allow_idle = omap2_clkt_iclk_allow_idle,
|
||||
.deny_idle = omap2_clkt_iclk_deny_idle,
|
||||
.find_idlest = am35xx_clk_ipss_find_idlest,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -37,34 +37,32 @@
|
|||
* (Any other value different from the Read value) to the
|
||||
* corresponding CM_CLKSEL register will refresh the dividers.
|
||||
*/
|
||||
static int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk)
|
||||
int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *clk)
|
||||
{
|
||||
struct clk_hw_omap *parent;
|
||||
struct clk_hw *parent_hw;
|
||||
u32 dummy_v, orig_v, clksel_shift;
|
||||
int ret;
|
||||
|
||||
/* Clear PWRDN bit of HSDIVIDER */
|
||||
ret = omap2_dflt_clk_enable(clk);
|
||||
|
||||
parent_hw = __clk_get_hw(__clk_get_parent(clk->clk));
|
||||
parent = to_clk_hw_omap(parent_hw);
|
||||
|
||||
/* Restore the dividers */
|
||||
if (!ret) {
|
||||
clksel_shift = __ffs(clk->parent->clksel_mask);
|
||||
orig_v = __raw_readl(clk->parent->clksel_reg);
|
||||
clksel_shift = __ffs(parent->clksel_mask);
|
||||
orig_v = __raw_readl(parent->clksel_reg);
|
||||
dummy_v = orig_v;
|
||||
|
||||
/* Write any other value different from the Read value */
|
||||
dummy_v ^= (1 << clksel_shift);
|
||||
__raw_writel(dummy_v, clk->parent->clksel_reg);
|
||||
__raw_writel(dummy_v, parent->clksel_reg);
|
||||
|
||||
/* Write the original divider */
|
||||
__raw_writel(orig_v, clk->parent->clksel_reg);
|
||||
__raw_writel(orig_v, parent->clksel_reg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore = {
|
||||
.enable = omap36xx_pwrdn_clk_enable_with_hsdiv_restore,
|
||||
.disable = omap2_dflt_clk_disable,
|
||||
.find_companion = omap2_clk_dflt_find_companion,
|
||||
.find_idlest = omap2_clk_dflt_find_idlest,
|
||||
};
|
||||
|
|
|
@ -8,6 +8,6 @@
|
|||
#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
|
||||
#define __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
|
||||
|
||||
extern const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
|
||||
extern int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *hw);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -38,8 +38,8 @@
|
|||
|
||||
/* needed by omap3_core_dpll_m2_set_rate() */
|
||||
struct clk *sdrc_ick_p, *arm_fck_p;
|
||||
|
||||
int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
|
||||
int omap3_dpll4_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
/*
|
||||
* According to the 12-5 CDP code from TI, "Limitation 2.5"
|
||||
|
@ -51,7 +51,7 @@ int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
return omap3_noncore_dpll_set_rate(clk, rate);
|
||||
return omap3_noncore_dpll_set_rate(hw, rate, parent_rate);
|
||||
}
|
||||
|
||||
void __init omap3_clk_lock_dpll5(void)
|
||||
|
|
|
@ -9,8 +9,10 @@
|
|||
#define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H
|
||||
|
||||
int omap3xxx_clk_init(void);
|
||||
int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
|
||||
int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
int omap3_core_dpll_m2_set_rate(struct clk_hw *clk, unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
void omap3_clk_lock_dpll5(void);
|
||||
|
||||
extern struct clk *sdrc_ick_p;
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -16,6 +16,7 @@
|
|||
* OMAP3xxx clock definition files.
|
||||
*/
|
||||
|
||||
#include <linux/clk-private.h>
|
||||
#include "clock.h"
|
||||
|
||||
/* clksel_rate data common to 24xx/343x */
|
||||
|
@ -52,6 +53,13 @@ const struct clksel_rate div_1_0_rates[] = {
|
|||
{ .div = 0 },
|
||||
};
|
||||
|
||||
const struct clksel_rate div3_1to4_rates[] = {
|
||||
{ .div = 1, .val = 0, .flags = RATE_IN_4430 },
|
||||
{ .div = 2, .val = 1, .flags = RATE_IN_4430 },
|
||||
{ .div = 4, .val = 2, .flags = RATE_IN_4430 },
|
||||
{ .div = 0 },
|
||||
};
|
||||
|
||||
const struct clksel_rate div_1_1_rates[] = {
|
||||
{ .div = 1, .val = 1, .flags = RATE_IN_4430 | RATE_IN_AM33XX },
|
||||
{ .div = 0 },
|
||||
|
@ -109,14 +117,10 @@ const struct clksel_rate div31_1to31_rates[] = {
|
|||
|
||||
/* Clocks shared between various OMAP SoCs */
|
||||
|
||||
struct clk virt_19200000_ck = {
|
||||
.name = "virt_19200000_ck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 19200000,
|
||||
};
|
||||
static struct clk_ops dummy_ck_ops = {};
|
||||
|
||||
struct clk virt_26000000_ck = {
|
||||
.name = "virt_26000000_ck",
|
||||
.ops = &clkops_null,
|
||||
.rate = 26000000,
|
||||
struct clk dummy_ck = {
|
||||
.name = "dummy_clk",
|
||||
.ops = &dummy_ck_ops,
|
||||
.flags = CLK_IS_BASIC,
|
||||
};
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/clk.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
|
@ -947,35 +948,6 @@ static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&clkdm->lock, flags);
|
||||
|
||||
if (atomic_read(&clkdm->usecount) == 0) {
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
WARN_ON(1); /* underflow */
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if (atomic_dec_return(&clkdm->usecount) > 0) {
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_clkdm->clkdm_clk_disable(clkdm);
|
||||
pwrdm_state_switch(clkdm->pwrdm.ptr);
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
|
||||
pr_debug("clockdomain: %s: disabled\n", clkdm->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* clkdm_clk_enable - add an enabled downstream clock to this clkdm
|
||||
* @clkdm: struct clockdomain *
|
||||
|
@ -1018,15 +990,37 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
|
|||
*/
|
||||
int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
|
||||
{
|
||||
/*
|
||||
* XXX Rewrite this code to maintain a list of enabled
|
||||
* downstream clocks for debugging purposes?
|
||||
*/
|
||||
unsigned long flags;
|
||||
|
||||
if (!clk)
|
||||
if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
|
||||
return -EINVAL;
|
||||
|
||||
return _clkdm_clk_hwmod_disable(clkdm);
|
||||
spin_lock_irqsave(&clkdm->lock, flags);
|
||||
|
||||
/* corner case: disabling unused clocks */
|
||||
if (__clk_get_enable_count(clk) == 0)
|
||||
goto ccd_exit;
|
||||
|
||||
if (atomic_read(&clkdm->usecount) == 0) {
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
WARN_ON(1); /* underflow */
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if (atomic_dec_return(&clkdm->usecount) > 0) {
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_clkdm->clkdm_clk_disable(clkdm);
|
||||
pwrdm_state_switch(clkdm->pwrdm.ptr);
|
||||
|
||||
pr_debug("clockdomain: %s: disabled\n", clkdm->name);
|
||||
|
||||
ccd_exit:
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1077,6 +1071,8 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
|
|||
*/
|
||||
int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/* The clkdm attribute does not exist yet prior OMAP4 */
|
||||
if (cpu_is_omap24xx() || cpu_is_omap34xx())
|
||||
return 0;
|
||||
|
@ -1086,9 +1082,28 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
|
|||
* downstream hwmods for debugging purposes?
|
||||
*/
|
||||
|
||||
if (!oh)
|
||||
if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
|
||||
return -EINVAL;
|
||||
|
||||
return _clkdm_clk_hwmod_disable(clkdm);
|
||||
spin_lock_irqsave(&clkdm->lock, flags);
|
||||
|
||||
if (atomic_read(&clkdm->usecount) == 0) {
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
WARN_ON(1); /* underflow */
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if (atomic_dec_return(&clkdm->usecount) > 0) {
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_clkdm->clkdm_clk_disable(clkdm);
|
||||
pwrdm_state_switch(clkdm->pwrdm.ptr);
|
||||
spin_unlock_irqrestore(&clkdm->lock, flags);
|
||||
|
||||
pr_debug("clockdomain: %s: disabled\n", clkdm->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,341 +0,0 @@
|
|||
/*
|
||||
* OMAP2 and OMAP3 clockdomain control
|
||||
*
|
||||
* Copyright (C) 2008-2010 Texas Instruments, Inc.
|
||||
* Copyright (C) 2008-2010 Nokia Corporation
|
||||
*
|
||||
* Derived from mach-omap2/clockdomain.c written by Paul Walmsley
|
||||
* Rajendra Nayak <rnayak@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <plat/prcm.h>
|
||||
|
||||
#include "soc.h"
|
||||
#include "prm.h"
|
||||
#include "prm2xxx_3xxx.h"
|
||||
#include "cm.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
#include "prm-regbits-24xx.h"
|
||||
#include "clockdomain.h"
|
||||
|
||||
static int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
|
||||
clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
|
||||
clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
|
||||
PM_WKDEP, (1 << clkdm2->dep_bit));
|
||||
}
|
||||
|
||||
static int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
|
||||
{
|
||||
struct clkdm_dep *cd;
|
||||
u32 mask = 0;
|
||||
|
||||
for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
|
||||
if (!cd->clkdm)
|
||||
continue; /* only happens if data is erroneous */
|
||||
|
||||
/* PRM accesses are slow, so minimize them */
|
||||
mask |= 1 << cd->clkdm->dep_bit;
|
||||
atomic_set(&cd->wkdep_usecount, 0);
|
||||
}
|
||||
|
||||
omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
|
||||
PM_WKDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3_clkdm_add_sleepdep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
|
||||
clkdm1->pwrdm.ptr->prcm_offs,
|
||||
OMAP3430_CM_SLEEPDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3_clkdm_del_sleepdep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
|
||||
clkdm1->pwrdm.ptr->prcm_offs,
|
||||
OMAP3430_CM_SLEEPDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3_clkdm_read_sleepdep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
|
||||
OMAP3430_CM_SLEEPDEP, (1 << clkdm2->dep_bit));
|
||||
}
|
||||
|
||||
static int omap3_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
|
||||
{
|
||||
struct clkdm_dep *cd;
|
||||
u32 mask = 0;
|
||||
|
||||
for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
|
||||
if (!cd->clkdm)
|
||||
continue; /* only happens if data is erroneous */
|
||||
|
||||
/* PRM accesses are slow, so minimize them */
|
||||
mask |= 1 << cd->clkdm->dep_bit;
|
||||
atomic_set(&cd->sleepdep_usecount, 0);
|
||||
}
|
||||
omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
|
||||
OMAP3430_CM_SLEEPDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2_clkdm_sleep(struct clockdomain *clkdm)
|
||||
{
|
||||
omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
|
||||
clkdm->pwrdm.ptr->prcm_offs,
|
||||
OMAP2_PM_PWSTCTRL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2_clkdm_wakeup(struct clockdomain *clkdm)
|
||||
{
|
||||
omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
|
||||
clkdm->pwrdm.ptr->prcm_offs,
|
||||
OMAP2_PM_PWSTCTRL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
if (atomic_read(&clkdm->usecount) > 0)
|
||||
_clkdm_add_autodeps(clkdm);
|
||||
|
||||
omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
}
|
||||
|
||||
static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
|
||||
if (atomic_read(&clkdm->usecount) > 0)
|
||||
_clkdm_del_autodeps(clkdm);
|
||||
}
|
||||
|
||||
static void _enable_hwsup(struct clockdomain *clkdm)
|
||||
{
|
||||
if (cpu_is_omap24xx())
|
||||
omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
else if (cpu_is_omap34xx())
|
||||
omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
}
|
||||
|
||||
static void _disable_hwsup(struct clockdomain *clkdm)
|
||||
{
|
||||
if (cpu_is_omap24xx())
|
||||
omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
else if (cpu_is_omap34xx())
|
||||
omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
}
|
||||
|
||||
static int omap3_clkdm_sleep(struct clockdomain *clkdm)
|
||||
{
|
||||
omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
|
||||
{
|
||||
omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
|
||||
{
|
||||
bool hwsup = false;
|
||||
|
||||
if (!clkdm->clktrctrl_mask)
|
||||
return 0;
|
||||
|
||||
hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
|
||||
if (hwsup) {
|
||||
/* Disable HW transitions when we are changing deps */
|
||||
_disable_hwsup(clkdm);
|
||||
_clkdm_add_autodeps(clkdm);
|
||||
_enable_hwsup(clkdm);
|
||||
} else {
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
|
||||
omap2_clkdm_wakeup(clkdm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
|
||||
{
|
||||
bool hwsup = false;
|
||||
|
||||
if (!clkdm->clktrctrl_mask)
|
||||
return 0;
|
||||
|
||||
hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
|
||||
if (hwsup) {
|
||||
/* Disable HW transitions when we are changing deps */
|
||||
_disable_hwsup(clkdm);
|
||||
_clkdm_del_autodeps(clkdm);
|
||||
_enable_hwsup(clkdm);
|
||||
} else {
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
|
||||
omap2_clkdm_sleep(clkdm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
if (atomic_read(&clkdm->usecount) > 0)
|
||||
_clkdm_add_autodeps(clkdm);
|
||||
|
||||
omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
}
|
||||
|
||||
static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
|
||||
if (atomic_read(&clkdm->usecount) > 0)
|
||||
_clkdm_del_autodeps(clkdm);
|
||||
}
|
||||
|
||||
static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
|
||||
{
|
||||
bool hwsup = false;
|
||||
|
||||
if (!clkdm->clktrctrl_mask)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The CLKDM_MISSING_IDLE_REPORTING flag documentation has
|
||||
* more details on the unpleasant problem this is working
|
||||
* around
|
||||
*/
|
||||
if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
|
||||
(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
|
||||
omap3_clkdm_wakeup(clkdm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
|
||||
if (hwsup) {
|
||||
/* Disable HW transitions when we are changing deps */
|
||||
_disable_hwsup(clkdm);
|
||||
_clkdm_add_autodeps(clkdm);
|
||||
_enable_hwsup(clkdm);
|
||||
} else {
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
|
||||
omap3_clkdm_wakeup(clkdm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
|
||||
{
|
||||
bool hwsup = false;
|
||||
|
||||
if (!clkdm->clktrctrl_mask)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The CLKDM_MISSING_IDLE_REPORTING flag documentation has
|
||||
* more details on the unpleasant problem this is working
|
||||
* around
|
||||
*/
|
||||
if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
|
||||
!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
|
||||
_enable_hwsup(clkdm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
|
||||
if (hwsup) {
|
||||
/* Disable HW transitions when we are changing deps */
|
||||
_disable_hwsup(clkdm);
|
||||
_clkdm_del_autodeps(clkdm);
|
||||
_enable_hwsup(clkdm);
|
||||
} else {
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
|
||||
omap3_clkdm_sleep(clkdm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct clkdm_ops omap2_clkdm_operations = {
|
||||
.clkdm_add_wkdep = omap2_clkdm_add_wkdep,
|
||||
.clkdm_del_wkdep = omap2_clkdm_del_wkdep,
|
||||
.clkdm_read_wkdep = omap2_clkdm_read_wkdep,
|
||||
.clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
|
||||
.clkdm_sleep = omap2_clkdm_sleep,
|
||||
.clkdm_wakeup = omap2_clkdm_wakeup,
|
||||
.clkdm_allow_idle = omap2_clkdm_allow_idle,
|
||||
.clkdm_deny_idle = omap2_clkdm_deny_idle,
|
||||
.clkdm_clk_enable = omap2_clkdm_clk_enable,
|
||||
.clkdm_clk_disable = omap2_clkdm_clk_disable,
|
||||
};
|
||||
|
||||
struct clkdm_ops omap3_clkdm_operations = {
|
||||
.clkdm_add_wkdep = omap2_clkdm_add_wkdep,
|
||||
.clkdm_del_wkdep = omap2_clkdm_del_wkdep,
|
||||
.clkdm_read_wkdep = omap2_clkdm_read_wkdep,
|
||||
.clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
|
||||
.clkdm_add_sleepdep = omap3_clkdm_add_sleepdep,
|
||||
.clkdm_del_sleepdep = omap3_clkdm_del_sleepdep,
|
||||
.clkdm_read_sleepdep = omap3_clkdm_read_sleepdep,
|
||||
.clkdm_clear_all_sleepdeps = omap3_clkdm_clear_all_sleepdeps,
|
||||
.clkdm_sleep = omap3_clkdm_sleep,
|
||||
.clkdm_wakeup = omap3_clkdm_wakeup,
|
||||
.clkdm_allow_idle = omap3_clkdm_allow_idle,
|
||||
.clkdm_deny_idle = omap3_clkdm_deny_idle,
|
||||
.clkdm_clk_enable = omap3xxx_clkdm_clk_enable,
|
||||
.clkdm_clk_disable = omap3xxx_clkdm_clk_disable,
|
||||
};
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* AM33XX clockdomain control
|
||||
*
|
||||
* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Vaibhav Hiremath <hvaibhav@ti.com>
|
||||
*
|
||||
* Derived from mach-omap2/clockdomain44xx.c written by Rajendra Nayak
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation version 2.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include "clockdomain.h"
|
||||
#include "cm33xx.h"
|
||||
|
||||
|
||||
static int am33xx_clkdm_sleep(struct clockdomain *clkdm)
|
||||
{
|
||||
am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int am33xx_clkdm_wakeup(struct clockdomain *clkdm)
|
||||
{
|
||||
am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
}
|
||||
|
||||
static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
}
|
||||
|
||||
static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm)
|
||||
{
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
|
||||
return am33xx_clkdm_wakeup(clkdm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
|
||||
{
|
||||
bool hwsup = false;
|
||||
|
||||
hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
|
||||
if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
|
||||
am33xx_clkdm_sleep(clkdm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct clkdm_ops am33xx_clkdm_operations = {
|
||||
.clkdm_sleep = am33xx_clkdm_sleep,
|
||||
.clkdm_wakeup = am33xx_clkdm_wakeup,
|
||||
.clkdm_allow_idle = am33xx_clkdm_allow_idle,
|
||||
.clkdm_deny_idle = am33xx_clkdm_deny_idle,
|
||||
.clkdm_clk_enable = am33xx_clkdm_clk_enable,
|
||||
.clkdm_clk_disable = am33xx_clkdm_clk_disable,
|
||||
};
|
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
* OMAP4 clockdomain control
|
||||
*
|
||||
* Copyright (C) 2008-2010 Texas Instruments, Inc.
|
||||
* Copyright (C) 2008-2010 Nokia Corporation
|
||||
*
|
||||
* Derived from mach-omap2/clockdomain.c written by Paul Walmsley
|
||||
* Rajendra Nayak <rnayak@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include "clockdomain.h"
|
||||
#include "cminst44xx.h"
|
||||
#include "cm44xx.h"
|
||||
|
||||
static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
|
||||
clkdm1->prcm_partition,
|
||||
clkdm1->cm_inst, clkdm1->clkdm_offs +
|
||||
OMAP4_CM_STATICDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
|
||||
clkdm1->prcm_partition,
|
||||
clkdm1->cm_inst, clkdm1->clkdm_offs +
|
||||
OMAP4_CM_STATICDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
|
||||
clkdm1->cm_inst, clkdm1->clkdm_offs +
|
||||
OMAP4_CM_STATICDEP,
|
||||
(1 << clkdm2->dep_bit));
|
||||
}
|
||||
|
||||
static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
|
||||
{
|
||||
struct clkdm_dep *cd;
|
||||
u32 mask = 0;
|
||||
|
||||
if (!clkdm->prcm_partition)
|
||||
return 0;
|
||||
|
||||
for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
|
||||
if (!cd->clkdm)
|
||||
continue; /* only happens if data is erroneous */
|
||||
|
||||
mask |= 1 << cd->clkdm->dep_bit;
|
||||
atomic_set(&cd->wkdep_usecount, 0);
|
||||
}
|
||||
|
||||
omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
|
||||
clkdm->cm_inst, clkdm->clkdm_offs +
|
||||
OMAP4_CM_STATICDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap4_clkdm_sleep(struct clockdomain *clkdm)
|
||||
{
|
||||
omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
|
||||
clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
|
||||
{
|
||||
omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
|
||||
clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
|
||||
clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
}
|
||||
|
||||
static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
|
||||
omap4_clkdm_wakeup(clkdm);
|
||||
else
|
||||
omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
|
||||
clkdm->cm_inst,
|
||||
clkdm->clkdm_offs);
|
||||
}
|
||||
|
||||
static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
|
||||
{
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
|
||||
return omap4_clkdm_wakeup(clkdm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
|
||||
{
|
||||
bool hwsup = false;
|
||||
|
||||
if (!clkdm->prcm_partition)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The CLKDM_MISSING_IDLE_REPORTING flag documentation has
|
||||
* more details on the unpleasant problem this is working
|
||||
* around
|
||||
*/
|
||||
if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
|
||||
!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
|
||||
omap4_clkdm_allow_idle(clkdm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
|
||||
clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
|
||||
if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
|
||||
omap4_clkdm_sleep(clkdm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct clkdm_ops omap4_clkdm_operations = {
|
||||
.clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep,
|
||||
.clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep,
|
||||
.clkdm_read_wkdep = omap4_clkdm_read_wkup_sleep_dep,
|
||||
.clkdm_clear_all_wkdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
|
||||
.clkdm_add_sleepdep = omap4_clkdm_add_wkup_sleep_dep,
|
||||
.clkdm_del_sleepdep = omap4_clkdm_del_wkup_sleep_dep,
|
||||
.clkdm_read_sleepdep = omap4_clkdm_read_wkup_sleep_dep,
|
||||
.clkdm_clear_all_sleepdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
|
||||
.clkdm_sleep = omap4_clkdm_sleep,
|
||||
.clkdm_wakeup = omap4_clkdm_wakeup,
|
||||
.clkdm_allow_idle = omap4_clkdm_allow_idle,
|
||||
.clkdm_deny_idle = omap4_clkdm_deny_idle,
|
||||
.clkdm_clk_enable = omap4_clkdm_clk_enable,
|
||||
.clkdm_clk_disable = omap4_clkdm_clk_disable,
|
||||
};
|
|
@ -59,6 +59,7 @@
|
|||
/* CM_CLKSEL_MPU */
|
||||
#define OMAP24XX_CLKSEL_MPU_SHIFT 0
|
||||
#define OMAP24XX_CLKSEL_MPU_MASK (0x1f << 0)
|
||||
#define OMAP24XX_CLKSEL_MPU_WIDTH 5
|
||||
|
||||
/* CM_CLKSTCTRL_MPU */
|
||||
#define OMAP24XX_AUTOSTATE_MPU_SHIFT 0
|
||||
|
@ -237,8 +238,10 @@
|
|||
#define OMAP24XX_CLKSEL_DSS1_MASK (0x1f << 8)
|
||||
#define OMAP24XX_CLKSEL_L4_SHIFT 5
|
||||
#define OMAP24XX_CLKSEL_L4_MASK (0x3 << 5)
|
||||
#define OMAP24XX_CLKSEL_L4_WIDTH 2
|
||||
#define OMAP24XX_CLKSEL_L3_SHIFT 0
|
||||
#define OMAP24XX_CLKSEL_L3_MASK (0x1f << 0)
|
||||
#define OMAP24XX_CLKSEL_L3_WIDTH 5
|
||||
|
||||
/* CM_CLKSEL2_CORE */
|
||||
#define OMAP24XX_CLKSEL_GPT12_SHIFT 22
|
||||
|
@ -333,7 +336,9 @@
|
|||
#define OMAP24XX_EN_DPLL_MASK (0x3 << 0)
|
||||
|
||||
/* CM_IDLEST_CKGEN */
|
||||
#define OMAP24XX_ST_54M_APLL_SHIFT 9
|
||||
#define OMAP24XX_ST_54M_APLL_MASK (1 << 9)
|
||||
#define OMAP24XX_ST_96M_APLL_SHIFT 8
|
||||
#define OMAP24XX_ST_96M_APLL_MASK (1 << 8)
|
||||
#define OMAP24XX_ST_54M_CLK_MASK (1 << 6)
|
||||
#define OMAP24XX_ST_12M_CLK_MASK (1 << 5)
|
||||
|
@ -361,8 +366,10 @@
|
|||
#define OMAP24XX_DPLL_DIV_MASK (0xf << 8)
|
||||
#define OMAP24XX_54M_SOURCE_SHIFT 5
|
||||
#define OMAP24XX_54M_SOURCE_MASK (1 << 5)
|
||||
#define OMAP24XX_54M_SOURCE_WIDTH 1
|
||||
#define OMAP2430_96M_SOURCE_SHIFT 4
|
||||
#define OMAP2430_96M_SOURCE_MASK (1 << 4)
|
||||
#define OMAP2430_96M_SOURCE_WIDTH 1
|
||||
#define OMAP24XX_48M_SOURCE_SHIFT 3
|
||||
#define OMAP24XX_48M_SOURCE_MASK (1 << 3)
|
||||
#define OMAP2430_ALTCLK_SOURCE_SHIFT 0
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
/* CM_CLKSEL1_PLL_IVA2 */
|
||||
#define OMAP3430_IVA2_CLK_SRC_SHIFT 19
|
||||
#define OMAP3430_IVA2_CLK_SRC_MASK (0x7 << 19)
|
||||
#define OMAP3430_IVA2_CLK_SRC_WIDTH 3
|
||||
#define OMAP3430_IVA2_DPLL_MULT_SHIFT 8
|
||||
#define OMAP3430_IVA2_DPLL_MULT_MASK (0x7ff << 8)
|
||||
#define OMAP3430_IVA2_DPLL_DIV_SHIFT 0
|
||||
|
@ -89,6 +90,7 @@
|
|||
/* CM_CLKSEL2_PLL_IVA2 */
|
||||
#define OMAP3430_IVA2_DPLL_CLKOUT_DIV_SHIFT 0
|
||||
#define OMAP3430_IVA2_DPLL_CLKOUT_DIV_MASK (0x1f << 0)
|
||||
#define OMAP3430_IVA2_DPLL_CLKOUT_DIV_WIDTH 5
|
||||
|
||||
/* CM_CLKSTCTRL_IVA2 */
|
||||
#define OMAP3430_CLKTRCTRL_IVA2_SHIFT 0
|
||||
|
@ -118,6 +120,7 @@
|
|||
/* CM_IDLEST_PLL_MPU */
|
||||
#define OMAP3430_ST_MPU_CLK_SHIFT 0
|
||||
#define OMAP3430_ST_MPU_CLK_MASK (1 << 0)
|
||||
#define OMAP3430_ST_MPU_CLK_WIDTH 1
|
||||
|
||||
/* CM_AUTOIDLE_PLL_MPU */
|
||||
#define OMAP3430_AUTO_MPU_DPLL_SHIFT 0
|
||||
|
@ -126,6 +129,7 @@
|
|||
/* CM_CLKSEL1_PLL_MPU */
|
||||
#define OMAP3430_MPU_CLK_SRC_SHIFT 19
|
||||
#define OMAP3430_MPU_CLK_SRC_MASK (0x7 << 19)
|
||||
#define OMAP3430_MPU_CLK_SRC_WIDTH 3
|
||||
#define OMAP3430_MPU_DPLL_MULT_SHIFT 8
|
||||
#define OMAP3430_MPU_DPLL_MULT_MASK (0x7ff << 8)
|
||||
#define OMAP3430_MPU_DPLL_DIV_SHIFT 0
|
||||
|
@ -134,6 +138,7 @@
|
|||
/* CM_CLKSEL2_PLL_MPU */
|
||||
#define OMAP3430_MPU_DPLL_CLKOUT_DIV_SHIFT 0
|
||||
#define OMAP3430_MPU_DPLL_CLKOUT_DIV_MASK (0x1f << 0)
|
||||
#define OMAP3430_MPU_DPLL_CLKOUT_DIV_WIDTH 5
|
||||
|
||||
/* CM_CLKSTCTRL_MPU */
|
||||
#define OMAP3430_CLKTRCTRL_MPU_SHIFT 0
|
||||
|
@ -345,10 +350,13 @@
|
|||
#define OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK (0x3 << 4)
|
||||
#define OMAP3430_CLKSEL_L4_SHIFT 2
|
||||
#define OMAP3430_CLKSEL_L4_MASK (0x3 << 2)
|
||||
#define OMAP3430_CLKSEL_L4_WIDTH 2
|
||||
#define OMAP3430_CLKSEL_L3_SHIFT 0
|
||||
#define OMAP3430_CLKSEL_L3_MASK (0x3 << 0)
|
||||
#define OMAP3430_CLKSEL_L3_WIDTH 2
|
||||
#define OMAP3630_CLKSEL_96M_SHIFT 12
|
||||
#define OMAP3630_CLKSEL_96M_MASK (0x3 << 12)
|
||||
#define OMAP3630_CLKSEL_96M_WIDTH 2
|
||||
|
||||
/* CM_CLKSTCTRL_CORE */
|
||||
#define OMAP3430ES1_CLKTRCTRL_D2D_SHIFT 4
|
||||
|
@ -452,6 +460,7 @@
|
|||
#define OMAP3430ES2_CLKSEL_USIMOCP_MASK (0xf << 3)
|
||||
#define OMAP3430_CLKSEL_RM_SHIFT 1
|
||||
#define OMAP3430_CLKSEL_RM_MASK (0x3 << 1)
|
||||
#define OMAP3430_CLKSEL_RM_WIDTH 2
|
||||
#define OMAP3430_CLKSEL_GPT1_SHIFT 0
|
||||
#define OMAP3430_CLKSEL_GPT1_MASK (1 << 0)
|
||||
|
||||
|
@ -520,14 +529,17 @@
|
|||
/* Note that OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK was (0x3 << 27) on 3430ES1 */
|
||||
#define OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT 27
|
||||
#define OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK (0x1f << 27)
|
||||
#define OMAP3430_CORE_DPLL_CLKOUT_DIV_WIDTH 5
|
||||
#define OMAP3430_CORE_DPLL_MULT_SHIFT 16
|
||||
#define OMAP3430_CORE_DPLL_MULT_MASK (0x7ff << 16)
|
||||
#define OMAP3430_CORE_DPLL_DIV_SHIFT 8
|
||||
#define OMAP3430_CORE_DPLL_DIV_MASK (0x7f << 8)
|
||||
#define OMAP3430_SOURCE_96M_SHIFT 6
|
||||
#define OMAP3430_SOURCE_96M_MASK (1 << 6)
|
||||
#define OMAP3430_SOURCE_96M_WIDTH 1
|
||||
#define OMAP3430_SOURCE_54M_SHIFT 5
|
||||
#define OMAP3430_SOURCE_54M_MASK (1 << 5)
|
||||
#define OMAP3430_SOURCE_54M_WIDTH 1
|
||||
#define OMAP3430_SOURCE_48M_SHIFT 3
|
||||
#define OMAP3430_SOURCE_48M_MASK (1 << 3)
|
||||
|
||||
|
@ -545,7 +557,9 @@
|
|||
/* CM_CLKSEL3_PLL */
|
||||
#define OMAP3430_DIV_96M_SHIFT 0
|
||||
#define OMAP3430_DIV_96M_MASK (0x1f << 0)
|
||||
#define OMAP3430_DIV_96M_WIDTH 5
|
||||
#define OMAP3630_DIV_96M_MASK (0x3f << 0)
|
||||
#define OMAP3630_DIV_96M_WIDTH 6
|
||||
|
||||
/* CM_CLKSEL4_PLL */
|
||||
#define OMAP3430ES2_PERIPH2_DPLL_MULT_SHIFT 8
|
||||
|
@ -556,12 +570,14 @@
|
|||
/* CM_CLKSEL5_PLL */
|
||||
#define OMAP3430ES2_DIV_120M_SHIFT 0
|
||||
#define OMAP3430ES2_DIV_120M_MASK (0x1f << 0)
|
||||
#define OMAP3430ES2_DIV_120M_WIDTH 5
|
||||
|
||||
/* CM_CLKOUT_CTRL */
|
||||
#define OMAP3430_CLKOUT2_EN_SHIFT 7
|
||||
#define OMAP3430_CLKOUT2_EN_MASK (1 << 7)
|
||||
#define OMAP3430_CLKOUT2_DIV_SHIFT 3
|
||||
#define OMAP3430_CLKOUT2_DIV_MASK (0x7 << 3)
|
||||
#define OMAP3430_CLKOUT2_DIV_WIDTH 3
|
||||
#define OMAP3430_CLKOUT2SOURCE_SHIFT 0
|
||||
#define OMAP3430_CLKOUT2SOURCE_MASK (0x3 << 0)
|
||||
|
||||
|
@ -592,10 +608,14 @@
|
|||
/* CM_CLKSEL_DSS */
|
||||
#define OMAP3430_CLKSEL_TV_SHIFT 8
|
||||
#define OMAP3430_CLKSEL_TV_MASK (0x1f << 8)
|
||||
#define OMAP3430_CLKSEL_TV_WIDTH 5
|
||||
#define OMAP3630_CLKSEL_TV_MASK (0x3f << 8)
|
||||
#define OMAP3630_CLKSEL_TV_WIDTH 6
|
||||
#define OMAP3430_CLKSEL_DSS1_SHIFT 0
|
||||
#define OMAP3430_CLKSEL_DSS1_MASK (0x1f << 0)
|
||||
#define OMAP3430_CLKSEL_DSS1_WIDTH 5
|
||||
#define OMAP3630_CLKSEL_DSS1_MASK (0x3f << 0)
|
||||
#define OMAP3630_CLKSEL_DSS1_WIDTH 6
|
||||
|
||||
/* CM_SLEEPDEP_DSS specific bits */
|
||||
|
||||
|
@ -623,7 +643,9 @@
|
|||
/* CM_CLKSEL_CAM */
|
||||
#define OMAP3430_CLKSEL_CAM_SHIFT 0
|
||||
#define OMAP3430_CLKSEL_CAM_MASK (0x1f << 0)
|
||||
#define OMAP3430_CLKSEL_CAM_WIDTH 5
|
||||
#define OMAP3630_CLKSEL_CAM_MASK (0x3f << 0)
|
||||
#define OMAP3630_CLKSEL_CAM_WIDTH 6
|
||||
|
||||
/* CM_SLEEPDEP_CAM specific bits */
|
||||
|
||||
|
@ -721,21 +743,30 @@
|
|||
/* CM_CLKSEL1_EMU */
|
||||
#define OMAP3430_DIV_DPLL4_SHIFT 24
|
||||
#define OMAP3430_DIV_DPLL4_MASK (0x1f << 24)
|
||||
#define OMAP3430_DIV_DPLL4_WIDTH 5
|
||||
#define OMAP3630_DIV_DPLL4_MASK (0x3f << 24)
|
||||
#define OMAP3630_DIV_DPLL4_WIDTH 6
|
||||
#define OMAP3430_DIV_DPLL3_SHIFT 16
|
||||
#define OMAP3430_DIV_DPLL3_MASK (0x1f << 16)
|
||||
#define OMAP3430_DIV_DPLL3_WIDTH 5
|
||||
#define OMAP3430_CLKSEL_TRACECLK_SHIFT 11
|
||||
#define OMAP3430_CLKSEL_TRACECLK_MASK (0x7 << 11)
|
||||
#define OMAP3430_CLKSEL_TRACECLK_WIDTH 3
|
||||
#define OMAP3430_CLKSEL_PCLK_SHIFT 8
|
||||
#define OMAP3430_CLKSEL_PCLK_MASK (0x7 << 8)
|
||||
#define OMAP3430_CLKSEL_PCLK_WIDTH 3
|
||||
#define OMAP3430_CLKSEL_PCLKX2_SHIFT 6
|
||||
#define OMAP3430_CLKSEL_PCLKX2_MASK (0x3 << 6)
|
||||
#define OMAP3430_CLKSEL_PCLKX2_WIDTH 2
|
||||
#define OMAP3430_CLKSEL_ATCLK_SHIFT 4
|
||||
#define OMAP3430_CLKSEL_ATCLK_MASK (0x3 << 4)
|
||||
#define OMAP3430_CLKSEL_ATCLK_WIDTH 2
|
||||
#define OMAP3430_TRACE_MUX_CTRL_SHIFT 2
|
||||
#define OMAP3430_TRACE_MUX_CTRL_MASK (0x3 << 2)
|
||||
#define OMAP3430_TRACE_MUX_CTRL_WIDTH 2
|
||||
#define OMAP3430_MUX_CTRL_SHIFT 0
|
||||
#define OMAP3430_MUX_CTRL_MASK (0x3 << 0)
|
||||
#define OMAP3430_MUX_CTRL_WIDTH 2
|
||||
|
||||
/* CM_CLKSTCTRL_EMU */
|
||||
#define OMAP3430_CLKTRCTRL_EMU_SHIFT 0
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* OMAP2+ Clock Management prototypes
|
||||
*
|
||||
* Copyright (C) 2007-2009 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2009, 2012 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2009 Nokia Corporation
|
||||
*
|
||||
* Written by Paul Walmsley
|
||||
|
@ -22,6 +22,12 @@
|
|||
*/
|
||||
#define MAX_MODULE_READY_TIME 2000
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
extern void __iomem *cm_base;
|
||||
extern void __iomem *cm2_base;
|
||||
extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2);
|
||||
# endif
|
||||
|
||||
/*
|
||||
* MAX_MODULE_DISABLE_TIME: max duration in microseconds to wait for
|
||||
* the PRCM to request that a module enter the inactive state in the
|
||||
|
@ -33,4 +39,26 @@
|
|||
*/
|
||||
#define MAX_MODULE_DISABLE_TIME 5000
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
|
||||
/**
|
||||
* struct cm_ll_data - fn ptrs to per-SoC CM function implementations
|
||||
* @split_idlest_reg: ptr to the SoC CM-specific split_idlest_reg impl
|
||||
* @wait_module_ready: ptr to the SoC CM-specific wait_module_ready impl
|
||||
*/
|
||||
struct cm_ll_data {
|
||||
int (*split_idlest_reg)(void __iomem *idlest_reg, s16 *prcm_inst,
|
||||
u8 *idlest_reg_id);
|
||||
int (*wait_module_ready)(s16 prcm_mod, u8 idlest_id, u8 idlest_shift);
|
||||
};
|
||||
|
||||
extern int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
|
||||
u8 *idlest_reg_id);
|
||||
extern int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift);
|
||||
|
||||
extern int cm_register(struct cm_ll_data *cld);
|
||||
extern int cm_unregister(struct cm_ll_data *cld);
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
|
381
arch/arm/mach-omap2/cm2xxx.c
Normal file
381
arch/arm/mach-omap2/cm2xxx.c
Normal file
|
@ -0,0 +1,381 @@
|
|||
/*
|
||||
* OMAP2xxx CM module functions
|
||||
*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Copyright (C) 2008-2010, 2012 Texas Instruments, Inc.
|
||||
* Paul Walmsley
|
||||
* Rajendra Nayak <rnayak@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "soc.h"
|
||||
#include "iomap.h"
|
||||
#include "common.h"
|
||||
#include "prm2xxx.h"
|
||||
#include "cm.h"
|
||||
#include "cm2xxx.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
#include "clockdomain.h"
|
||||
|
||||
/* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */
|
||||
#define DPLL_AUTOIDLE_DISABLE 0x0
|
||||
#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP 0x3
|
||||
|
||||
/* CM_AUTOIDLE_PLL.AUTO_* bit values for APLLs (OMAP2xxx only) */
|
||||
#define OMAP2XXX_APLL_AUTOIDLE_DISABLE 0x0
|
||||
#define OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP 0x3
|
||||
|
||||
/* CM_IDLEST_PLL bit value offset for APLLs (OMAP2xxx only) */
|
||||
#define EN_APLL_LOCKED 3
|
||||
|
||||
static const u8 omap2xxx_cm_idlest_offs[] = {
|
||||
CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3, OMAP24XX_CM_IDLEST4
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static void _write_clktrctrl(u8 c, s16 module, u32 mask)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
|
||||
v &= ~mask;
|
||||
v |= c << __ffs(mask);
|
||||
omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
|
||||
}
|
||||
|
||||
bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
|
||||
v &= mask;
|
||||
v >>= __ffs(mask);
|
||||
|
||||
return (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
|
||||
}
|
||||
|
||||
void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
|
||||
{
|
||||
_write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
|
||||
{
|
||||
_write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* DPLL autoidle control
|
||||
*/
|
||||
|
||||
static void _omap2xxx_set_dpll_autoidle(u8 m)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
|
||||
v &= ~OMAP24XX_AUTO_DPLL_MASK;
|
||||
v |= m << OMAP24XX_AUTO_DPLL_SHIFT;
|
||||
omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_set_dpll_disable_autoidle(void)
|
||||
{
|
||||
_omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_set_dpll_auto_low_power_stop(void)
|
||||
{
|
||||
_omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE);
|
||||
}
|
||||
|
||||
/*
|
||||
* APLL control
|
||||
*/
|
||||
|
||||
static void _omap2xxx_set_apll_autoidle(u8 m, u32 mask)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
|
||||
v &= ~mask;
|
||||
v |= m << __ffs(mask);
|
||||
omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_set_apll54_disable_autoidle(void)
|
||||
{
|
||||
_omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
|
||||
OMAP24XX_AUTO_54M_MASK);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_set_apll54_auto_low_power_stop(void)
|
||||
{
|
||||
_omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
|
||||
OMAP24XX_AUTO_54M_MASK);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_set_apll96_disable_autoidle(void)
|
||||
{
|
||||
_omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
|
||||
OMAP24XX_AUTO_96M_MASK);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_set_apll96_auto_low_power_stop(void)
|
||||
{
|
||||
_omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
|
||||
OMAP24XX_AUTO_96M_MASK);
|
||||
}
|
||||
|
||||
/* Enable an APLL if off */
|
||||
static int _omap2xxx_apll_enable(u8 enable_bit, u8 status_bit)
|
||||
{
|
||||
u32 v, m;
|
||||
|
||||
m = EN_APLL_LOCKED << enable_bit;
|
||||
|
||||
v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
|
||||
if (v & m)
|
||||
return 0; /* apll already enabled */
|
||||
|
||||
v |= m;
|
||||
omap2_cm_write_mod_reg(v, PLL_MOD, CM_CLKEN);
|
||||
|
||||
omap2xxx_cm_wait_module_ready(PLL_MOD, 1, status_bit);
|
||||
|
||||
/*
|
||||
* REVISIT: Should we return an error code if
|
||||
* omap2xxx_cm_wait_module_ready() fails?
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Stop APLL */
|
||||
static void _omap2xxx_apll_disable(u8 enable_bit)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
|
||||
v &= ~(EN_APLL_LOCKED << enable_bit);
|
||||
omap2_cm_write_mod_reg(v, PLL_MOD, CM_CLKEN);
|
||||
}
|
||||
|
||||
/* Enable an APLL if off */
|
||||
int omap2xxx_cm_apll54_enable(void)
|
||||
{
|
||||
return _omap2xxx_apll_enable(OMAP24XX_EN_54M_PLL_SHIFT,
|
||||
OMAP24XX_ST_54M_APLL_SHIFT);
|
||||
}
|
||||
|
||||
/* Enable an APLL if off */
|
||||
int omap2xxx_cm_apll96_enable(void)
|
||||
{
|
||||
return _omap2xxx_apll_enable(OMAP24XX_EN_96M_PLL_SHIFT,
|
||||
OMAP24XX_ST_96M_APLL_SHIFT);
|
||||
}
|
||||
|
||||
/* Stop APLL */
|
||||
void omap2xxx_cm_apll54_disable(void)
|
||||
{
|
||||
_omap2xxx_apll_disable(OMAP24XX_EN_54M_PLL_SHIFT);
|
||||
}
|
||||
|
||||
/* Stop APLL */
|
||||
void omap2xxx_cm_apll96_disable(void)
|
||||
{
|
||||
_omap2xxx_apll_disable(OMAP24XX_EN_96M_PLL_SHIFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2xxx_cm_split_idlest_reg - split CM_IDLEST reg addr into its components
|
||||
* @idlest_reg: CM_IDLEST* virtual address
|
||||
* @prcm_inst: pointer to an s16 to return the PRCM instance offset
|
||||
* @idlest_reg_id: pointer to a u8 to return the CM_IDLESTx register ID
|
||||
*
|
||||
* XXX This function is only needed until absolute register addresses are
|
||||
* removed from the OMAP struct clk records.
|
||||
*/
|
||||
int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
|
||||
u8 *idlest_reg_id)
|
||||
{
|
||||
unsigned long offs;
|
||||
u8 idlest_offs;
|
||||
int i;
|
||||
|
||||
if (idlest_reg < cm_base || idlest_reg > (cm_base + 0x0fff))
|
||||
return -EINVAL;
|
||||
|
||||
idlest_offs = (unsigned long)idlest_reg & 0xff;
|
||||
for (i = 0; i < ARRAY_SIZE(omap2xxx_cm_idlest_offs); i++) {
|
||||
if (idlest_offs == omap2xxx_cm_idlest_offs[i]) {
|
||||
*idlest_reg_id = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(omap2xxx_cm_idlest_offs))
|
||||
return -EINVAL;
|
||||
|
||||
offs = idlest_reg - cm_base;
|
||||
offs &= 0xff00;
|
||||
*prcm_inst = offs;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* omap2xxx_cm_wait_module_ready - wait for a module to leave idle or standby
|
||||
* @prcm_mod: PRCM module offset
|
||||
* @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
|
||||
* @idlest_shift: shift of the bit in the CM_IDLEST* register to check
|
||||
*
|
||||
* Wait for the PRCM to indicate that the module identified by
|
||||
* (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon
|
||||
* success or -EBUSY if the module doesn't enable in time.
|
||||
*/
|
||||
int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
|
||||
{
|
||||
int ena = 0, i = 0;
|
||||
u8 cm_idlest_reg;
|
||||
u32 mask;
|
||||
|
||||
if (!idlest_id || (idlest_id > ARRAY_SIZE(omap2xxx_cm_idlest_offs)))
|
||||
return -EINVAL;
|
||||
|
||||
cm_idlest_reg = omap2xxx_cm_idlest_offs[idlest_id - 1];
|
||||
|
||||
mask = 1 << idlest_shift;
|
||||
ena = mask;
|
||||
|
||||
omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) &
|
||||
mask) == ena), MAX_MODULE_READY_TIME, i);
|
||||
|
||||
return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
|
||||
}
|
||||
|
||||
/* Clockdomain low-level functions */
|
||||
|
||||
static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
if (atomic_read(&clkdm->usecount) > 0)
|
||||
_clkdm_add_autodeps(clkdm);
|
||||
|
||||
omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
}
|
||||
|
||||
static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
|
||||
if (atomic_read(&clkdm->usecount) > 0)
|
||||
_clkdm_del_autodeps(clkdm);
|
||||
}
|
||||
|
||||
static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)
|
||||
{
|
||||
bool hwsup = false;
|
||||
|
||||
if (!clkdm->clktrctrl_mask)
|
||||
return 0;
|
||||
|
||||
hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
|
||||
if (hwsup) {
|
||||
/* Disable HW transitions when we are changing deps */
|
||||
omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
_clkdm_add_autodeps(clkdm);
|
||||
omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
} else {
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
|
||||
omap2xxx_clkdm_wakeup(clkdm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)
|
||||
{
|
||||
bool hwsup = false;
|
||||
|
||||
if (!clkdm->clktrctrl_mask)
|
||||
return 0;
|
||||
|
||||
hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
|
||||
if (hwsup) {
|
||||
/* Disable HW transitions when we are changing deps */
|
||||
omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
_clkdm_del_autodeps(clkdm);
|
||||
omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
} else {
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
|
||||
omap2xxx_clkdm_sleep(clkdm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct clkdm_ops omap2_clkdm_operations = {
|
||||
.clkdm_add_wkdep = omap2_clkdm_add_wkdep,
|
||||
.clkdm_del_wkdep = omap2_clkdm_del_wkdep,
|
||||
.clkdm_read_wkdep = omap2_clkdm_read_wkdep,
|
||||
.clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
|
||||
.clkdm_sleep = omap2xxx_clkdm_sleep,
|
||||
.clkdm_wakeup = omap2xxx_clkdm_wakeup,
|
||||
.clkdm_allow_idle = omap2xxx_clkdm_allow_idle,
|
||||
.clkdm_deny_idle = omap2xxx_clkdm_deny_idle,
|
||||
.clkdm_clk_enable = omap2xxx_clkdm_clk_enable,
|
||||
.clkdm_clk_disable = omap2xxx_clkdm_clk_disable,
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static struct cm_ll_data omap2xxx_cm_ll_data = {
|
||||
.split_idlest_reg = &omap2xxx_cm_split_idlest_reg,
|
||||
.wait_module_ready = &omap2xxx_cm_wait_module_ready,
|
||||
};
|
||||
|
||||
int __init omap2xxx_cm_init(void)
|
||||
{
|
||||
if (!cpu_is_omap24xx())
|
||||
return 0;
|
||||
|
||||
return cm_register(&omap2xxx_cm_ll_data);
|
||||
}
|
||||
|
||||
static void __exit omap2xxx_cm_exit(void)
|
||||
{
|
||||
if (!cpu_is_omap24xx())
|
||||
return;
|
||||
|
||||
/* Should never happen */
|
||||
WARN(cm_unregister(&omap2xxx_cm_ll_data),
|
||||
"%s: cm_ll_data function pointer mismatch\n", __func__);
|
||||
}
|
||||
__exitcall(omap2xxx_cm_exit);
|
70
arch/arm/mach-omap2/cm2xxx.h
Normal file
70
arch/arm/mach-omap2/cm2xxx.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* OMAP2xxx Clock Management (CM) register definitions
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2012 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2010 Nokia Corporation
|
||||
* Paul Walmsley
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The CM hardware modules on the OMAP2/3 are quite similar to each
|
||||
* other. The CM modules/instances on OMAP4 are quite different, so
|
||||
* they are handled in a separate file.
|
||||
*/
|
||||
#ifndef __ARCH_ASM_MACH_OMAP2_CM2XXX_H
|
||||
#define __ARCH_ASM_MACH_OMAP2_CM2XXX_H
|
||||
|
||||
#include "prcm-common.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
|
||||
#define OMAP2420_CM_REGADDR(module, reg) \
|
||||
OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
|
||||
#define OMAP2430_CM_REGADDR(module, reg) \
|
||||
OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
|
||||
|
||||
/*
|
||||
* Module specific CM register offsets from CM_BASE + domain offset
|
||||
* Use cm_{read,write}_mod_reg() with these registers.
|
||||
* These register offsets generally appear in more than one PRCM submodule.
|
||||
*/
|
||||
|
||||
/* OMAP2-specific register offsets */
|
||||
|
||||
#define OMAP24XX_CM_FCLKEN2 0x0004
|
||||
#define OMAP24XX_CM_ICLKEN4 0x001c
|
||||
#define OMAP24XX_CM_AUTOIDLE4 0x003c
|
||||
#define OMAP24XX_CM_IDLEST4 0x002c
|
||||
|
||||
/* CM_IDLEST bit field values to indicate deasserted IdleReq */
|
||||
|
||||
#define OMAP24XX_CM_IDLEST_VAL 0
|
||||
|
||||
|
||||
/* Clock management domain register get/set */
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
|
||||
extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
|
||||
|
||||
extern void omap2xxx_cm_set_dpll_disable_autoidle(void);
|
||||
extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void);
|
||||
|
||||
extern void omap2xxx_cm_set_apll54_disable_autoidle(void);
|
||||
extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void);
|
||||
extern void omap2xxx_cm_set_apll96_disable_autoidle(void);
|
||||
extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
|
||||
|
||||
extern bool omap2xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
|
||||
extern int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
|
||||
u8 idlest_shift);
|
||||
extern int omap2xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
|
||||
s16 *prcm_inst, u8 *idlest_reg_id);
|
||||
|
||||
extern int __init omap2xxx_cm_init(void);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -16,28 +16,7 @@
|
|||
#ifndef __ARCH_ASM_MACH_OMAP2_CM2XXX_3XXX_H
|
||||
#define __ARCH_ASM_MACH_OMAP2_CM2XXX_3XXX_H
|
||||
|
||||
#include "prcm-common.h"
|
||||
|
||||
#define OMAP2420_CM_REGADDR(module, reg) \
|
||||
OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
|
||||
#define OMAP2430_CM_REGADDR(module, reg) \
|
||||
OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
|
||||
#define OMAP34XX_CM_REGADDR(module, reg) \
|
||||
OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
|
||||
|
||||
|
||||
/*
|
||||
* OMAP3-specific global CM registers
|
||||
* Use cm_{read,write}_reg() with these registers.
|
||||
* These registers appear once per CM module.
|
||||
*/
|
||||
|
||||
#define OMAP3430_CM_REVISION OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000)
|
||||
#define OMAP3430_CM_SYSCONFIG OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010)
|
||||
#define OMAP3430_CM_POLCTRL OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c)
|
||||
|
||||
#define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070
|
||||
#define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
|
||||
#include "cm.h"
|
||||
|
||||
/*
|
||||
* Module specific CM register offsets from CM_BASE + domain offset
|
||||
|
@ -57,6 +36,7 @@
|
|||
#define CM_IDLEST 0x0020
|
||||
#define CM_IDLEST1 CM_IDLEST
|
||||
#define CM_IDLEST2 0x0024
|
||||
#define OMAP2430_CM_IDLEST3 0x0028
|
||||
#define CM_AUTOIDLE 0x0030
|
||||
#define CM_AUTOIDLE1 CM_AUTOIDLE
|
||||
#define CM_AUTOIDLE2 0x0034
|
||||
|
@ -66,70 +46,60 @@
|
|||
#define CM_CLKSEL2 0x0044
|
||||
#define OMAP2_CM_CLKSTCTRL 0x0048
|
||||
|
||||
/* OMAP2-specific register offsets */
|
||||
|
||||
#define OMAP24XX_CM_FCLKEN2 0x0004
|
||||
#define OMAP24XX_CM_ICLKEN4 0x001c
|
||||
#define OMAP24XX_CM_AUTOIDLE4 0x003c
|
||||
#define OMAP24XX_CM_IDLEST4 0x002c
|
||||
|
||||
#define OMAP2430_CM_IDLEST3 0x0028
|
||||
|
||||
/* OMAP3-specific register offsets */
|
||||
|
||||
#define OMAP3430_CM_CLKEN_PLL 0x0004
|
||||
#define OMAP3430ES2_CM_CLKEN2 0x0004
|
||||
#define OMAP3430ES2_CM_FCLKEN3 0x0008
|
||||
#define OMAP3430_CM_IDLEST_PLL CM_IDLEST2
|
||||
#define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2
|
||||
#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2
|
||||
#define OMAP3430_CM_CLKSEL1 CM_CLKSEL
|
||||
#define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL
|
||||
#define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2
|
||||
#define OMAP3430_CM_SLEEPDEP CM_CLKSEL2
|
||||
#define OMAP3430_CM_CLKSEL3 OMAP2_CM_CLKSTCTRL
|
||||
#define OMAP3430_CM_CLKSTST 0x004c
|
||||
#define OMAP3430ES2_CM_CLKSEL4 0x004c
|
||||
#define OMAP3430ES2_CM_CLKSEL5 0x0050
|
||||
#define OMAP3430_CM_CLKSEL2_EMU 0x0050
|
||||
#define OMAP3430_CM_CLKSEL3_EMU 0x0054
|
||||
|
||||
|
||||
/* CM_IDLEST bit field values to indicate deasserted IdleReq */
|
||||
|
||||
#define OMAP24XX_CM_IDLEST_VAL 0
|
||||
#define OMAP34XX_CM_IDLEST_VAL 1
|
||||
|
||||
|
||||
/* Clock management domain register get/set */
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
extern u32 omap2_cm_read_mod_reg(s16 module, u16 idx);
|
||||
extern void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx);
|
||||
extern u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
|
||||
#include <linux/io.h>
|
||||
|
||||
extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
|
||||
u8 idlest_shift);
|
||||
extern u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx);
|
||||
extern u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx);
|
||||
static inline u32 omap2_cm_read_mod_reg(s16 module, u16 idx)
|
||||
{
|
||||
return __raw_readl(cm_base + module + idx);
|
||||
}
|
||||
|
||||
extern bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
|
||||
extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
|
||||
extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
|
||||
static inline void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx)
|
||||
{
|
||||
__raw_writel(val, cm_base + module + idx);
|
||||
}
|
||||
|
||||
extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
|
||||
extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
|
||||
extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
|
||||
extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
|
||||
/* Read-modify-write a register in a CM module. Caller must lock */
|
||||
static inline u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module,
|
||||
s16 idx)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
extern void omap2xxx_cm_set_dpll_disable_autoidle(void);
|
||||
extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void);
|
||||
v = omap2_cm_read_mod_reg(module, idx);
|
||||
v &= ~mask;
|
||||
v |= bits;
|
||||
omap2_cm_write_mod_reg(v, module, idx);
|
||||
|
||||
extern void omap2xxx_cm_set_apll54_disable_autoidle(void);
|
||||
extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void);
|
||||
extern void omap2xxx_cm_set_apll96_disable_autoidle(void);
|
||||
extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
|
||||
return v;
|
||||
}
|
||||
|
||||
/* Read a CM register, AND it, and shift the result down to bit 0 */
|
||||
static inline u32 omap2_cm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
v = omap2_cm_read_mod_reg(domain, idx);
|
||||
v &= mask;
|
||||
v >>= __ffs(mask);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
|
||||
{
|
||||
return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
|
||||
}
|
||||
|
||||
static inline u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
|
||||
{
|
||||
return omap2_cm_rmw_mod_reg_bits(bits, 0x0, module, idx);
|
||||
}
|
||||
|
||||
extern int omap2xxx_cm_apll54_enable(void);
|
||||
extern void omap2xxx_cm_apll54_disable(void);
|
||||
extern int omap2xxx_cm_apll96_enable(void);
|
||||
extern void omap2xxx_cm_apll96_disable(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -138,6 +108,7 @@ extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
|
|||
/* CM_CLKSEL_GFX */
|
||||
#define OMAP_CLKSEL_GFX_SHIFT 0
|
||||
#define OMAP_CLKSEL_GFX_MASK (0x7 << 0)
|
||||
#define OMAP_CLKSEL_GFX_WIDTH 3
|
||||
|
||||
/* CM_ICLKEN_GFX */
|
||||
#define OMAP_EN_GFX_SHIFT 0
|
||||
|
@ -146,11 +117,4 @@ extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
|
|||
/* CM_IDLEST_GFX */
|
||||
#define OMAP_ST_GFX_MASK (1 << 0)
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
# ifndef __ASSEMBLER__
|
||||
extern void omap3_cm_save_context(void);
|
||||
extern void omap3_cm_restore_context(void);
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "clockdomain.h"
|
||||
#include "cm.h"
|
||||
#include "cm33xx.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
|
@ -309,3 +310,58 @@ void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs)
|
|||
v &= ~AM33XX_MODULEMODE_MASK;
|
||||
am33xx_cm_write_reg(v, inst, clkctrl_offs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clockdomain low-level functions
|
||||
*/
|
||||
|
||||
static int am33xx_clkdm_sleep(struct clockdomain *clkdm)
|
||||
{
|
||||
am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int am33xx_clkdm_wakeup(struct clockdomain *clkdm)
|
||||
{
|
||||
am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
}
|
||||
|
||||
static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
}
|
||||
|
||||
static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm)
|
||||
{
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
|
||||
return am33xx_clkdm_wakeup(clkdm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
|
||||
{
|
||||
bool hwsup = false;
|
||||
|
||||
hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
|
||||
if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
|
||||
am33xx_clkdm_sleep(clkdm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct clkdm_ops am33xx_clkdm_operations = {
|
||||
.clkdm_sleep = am33xx_clkdm_sleep,
|
||||
.clkdm_wakeup = am33xx_clkdm_wakeup,
|
||||
.clkdm_allow_idle = am33xx_clkdm_allow_idle,
|
||||
.clkdm_deny_idle = am33xx_clkdm_deny_idle,
|
||||
.clkdm_clk_enable = am33xx_clkdm_clk_enable,
|
||||
.clkdm_clk_disable = am33xx_clkdm_clk_disable,
|
||||
};
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* OMAP2/3 CM module functions
|
||||
* OMAP3xxx CM module functions
|
||||
*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Copyright (C) 2008-2010, 2012 Texas Instruments, Inc.
|
||||
* Paul Walmsley
|
||||
* Rajendra Nayak <rnayak@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -12,8 +14,6 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -21,56 +21,16 @@
|
|||
#include "soc.h"
|
||||
#include "iomap.h"
|
||||
#include "common.h"
|
||||
#include "prm2xxx_3xxx.h"
|
||||
#include "cm.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
#include "cm-regbits-24xx.h"
|
||||
#include "cm3xxx.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
#include "clockdomain.h"
|
||||
|
||||
/* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */
|
||||
#define DPLL_AUTOIDLE_DISABLE 0x0
|
||||
#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP 0x3
|
||||
|
||||
/* CM_AUTOIDLE_PLL.AUTO_* bit values for APLLs (OMAP2xxx only) */
|
||||
#define OMAP2XXX_APLL_AUTOIDLE_DISABLE 0x0
|
||||
#define OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP 0x3
|
||||
|
||||
static const u8 cm_idlest_offs[] = {
|
||||
CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3, OMAP24XX_CM_IDLEST4
|
||||
static const u8 omap3xxx_cm_idlest_offs[] = {
|
||||
CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
|
||||
};
|
||||
|
||||
u32 omap2_cm_read_mod_reg(s16 module, u16 idx)
|
||||
{
|
||||
return __raw_readl(cm_base + module + idx);
|
||||
}
|
||||
|
||||
void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx)
|
||||
{
|
||||
__raw_writel(val, cm_base + module + idx);
|
||||
}
|
||||
|
||||
/* Read-modify-write a register in a CM module. Caller must lock */
|
||||
u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
v = omap2_cm_read_mod_reg(module, idx);
|
||||
v &= ~mask;
|
||||
v |= bits;
|
||||
omap2_cm_write_mod_reg(v, module, idx);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
|
||||
{
|
||||
return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
|
||||
}
|
||||
|
||||
u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
|
||||
{
|
||||
return omap2_cm_rmw_mod_reg_bits(bits, 0x0, module, idx);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
@ -85,33 +45,15 @@ static void _write_clktrctrl(u8 c, s16 module, u32 mask)
|
|||
omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
|
||||
}
|
||||
|
||||
bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
|
||||
bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
|
||||
{
|
||||
u32 v;
|
||||
bool ret = 0;
|
||||
|
||||
BUG_ON(!cpu_is_omap24xx() && !cpu_is_omap34xx());
|
||||
|
||||
v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
|
||||
v &= mask;
|
||||
v >>= __ffs(mask);
|
||||
|
||||
if (cpu_is_omap24xx())
|
||||
ret = (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
|
||||
else
|
||||
ret = (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
|
||||
{
|
||||
_write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
|
||||
{
|
||||
_write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
|
||||
return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
|
||||
}
|
||||
|
||||
void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
|
||||
|
@ -134,110 +76,248 @@ void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
|
|||
_write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* DPLL autoidle control
|
||||
*/
|
||||
|
||||
static void _omap2xxx_set_dpll_autoidle(u8 m)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
|
||||
v &= ~OMAP24XX_AUTO_DPLL_MASK;
|
||||
v |= m << OMAP24XX_AUTO_DPLL_SHIFT;
|
||||
omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_set_dpll_disable_autoidle(void)
|
||||
{
|
||||
_omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_set_dpll_auto_low_power_stop(void)
|
||||
{
|
||||
_omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE);
|
||||
}
|
||||
|
||||
/*
|
||||
* APLL autoidle control
|
||||
*/
|
||||
|
||||
static void _omap2xxx_set_apll_autoidle(u8 m, u32 mask)
|
||||
{
|
||||
u32 v;
|
||||
|
||||
v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
|
||||
v &= ~mask;
|
||||
v |= m << __ffs(mask);
|
||||
omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_set_apll54_disable_autoidle(void)
|
||||
{
|
||||
_omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
|
||||
OMAP24XX_AUTO_54M_MASK);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_set_apll54_auto_low_power_stop(void)
|
||||
{
|
||||
_omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
|
||||
OMAP24XX_AUTO_54M_MASK);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_set_apll96_disable_autoidle(void)
|
||||
{
|
||||
_omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
|
||||
OMAP24XX_AUTO_96M_MASK);
|
||||
}
|
||||
|
||||
void omap2xxx_cm_set_apll96_auto_low_power_stop(void)
|
||||
{
|
||||
_omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
|
||||
OMAP24XX_AUTO_96M_MASK);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* omap2_cm_wait_idlest_ready - wait for a module to leave idle or standby
|
||||
* omap3xxx_cm_wait_module_ready - wait for a module to leave idle or standby
|
||||
* @prcm_mod: PRCM module offset
|
||||
* @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
|
||||
* @idlest_shift: shift of the bit in the CM_IDLEST* register to check
|
||||
*
|
||||
* XXX document
|
||||
* Wait for the PRCM to indicate that the module identified by
|
||||
* (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon
|
||||
* success or -EBUSY if the module doesn't enable in time.
|
||||
*/
|
||||
int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
|
||||
int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
|
||||
{
|
||||
int ena = 0, i = 0;
|
||||
u8 cm_idlest_reg;
|
||||
u32 mask;
|
||||
|
||||
if (!idlest_id || (idlest_id > ARRAY_SIZE(cm_idlest_offs)))
|
||||
if (!idlest_id || (idlest_id > ARRAY_SIZE(omap3xxx_cm_idlest_offs)))
|
||||
return -EINVAL;
|
||||
|
||||
cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
|
||||
cm_idlest_reg = omap3xxx_cm_idlest_offs[idlest_id - 1];
|
||||
|
||||
mask = 1 << idlest_shift;
|
||||
ena = 0;
|
||||
|
||||
if (cpu_is_omap24xx())
|
||||
ena = mask;
|
||||
else if (cpu_is_omap34xx())
|
||||
ena = 0;
|
||||
else
|
||||
BUG();
|
||||
|
||||
omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena),
|
||||
MAX_MODULE_READY_TIME, i);
|
||||
omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) &
|
||||
mask) == ena), MAX_MODULE_READY_TIME, i);
|
||||
|
||||
return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap3xxx_cm_split_idlest_reg - split CM_IDLEST reg addr into its components
|
||||
* @idlest_reg: CM_IDLEST* virtual address
|
||||
* @prcm_inst: pointer to an s16 to return the PRCM instance offset
|
||||
* @idlest_reg_id: pointer to a u8 to return the CM_IDLESTx register ID
|
||||
*
|
||||
* XXX This function is only needed until absolute register addresses are
|
||||
* removed from the OMAP struct clk records.
|
||||
*/
|
||||
int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
|
||||
u8 *idlest_reg_id)
|
||||
{
|
||||
unsigned long offs;
|
||||
u8 idlest_offs;
|
||||
int i;
|
||||
|
||||
if (idlest_reg < (cm_base + OMAP3430_IVA2_MOD) ||
|
||||
idlest_reg > (cm_base + 0x1ffff))
|
||||
return -EINVAL;
|
||||
|
||||
idlest_offs = (unsigned long)idlest_reg & 0xff;
|
||||
for (i = 0; i < ARRAY_SIZE(omap3xxx_cm_idlest_offs); i++) {
|
||||
if (idlest_offs == omap3xxx_cm_idlest_offs[i]) {
|
||||
*idlest_reg_id = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(omap3xxx_cm_idlest_offs))
|
||||
return -EINVAL;
|
||||
|
||||
offs = idlest_reg - cm_base;
|
||||
offs &= 0xff00;
|
||||
*prcm_inst = offs;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Clockdomain low-level operations */
|
||||
|
||||
static int omap3xxx_clkdm_add_sleepdep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
|
||||
clkdm1->pwrdm.ptr->prcm_offs,
|
||||
OMAP3430_CM_SLEEPDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3xxx_clkdm_del_sleepdep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
|
||||
clkdm1->pwrdm.ptr->prcm_offs,
|
||||
OMAP3430_CM_SLEEPDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3xxx_clkdm_read_sleepdep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
return omap2_cm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
|
||||
OMAP3430_CM_SLEEPDEP,
|
||||
(1 << clkdm2->dep_bit));
|
||||
}
|
||||
|
||||
static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
|
||||
{
|
||||
struct clkdm_dep *cd;
|
||||
u32 mask = 0;
|
||||
|
||||
for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
|
||||
if (!cd->clkdm)
|
||||
continue; /* only happens if data is erroneous */
|
||||
|
||||
mask |= 1 << cd->clkdm->dep_bit;
|
||||
atomic_set(&cd->sleepdep_usecount, 0);
|
||||
}
|
||||
omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
|
||||
OMAP3430_CM_SLEEPDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3xxx_clkdm_sleep(struct clockdomain *clkdm)
|
||||
{
|
||||
omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm)
|
||||
{
|
||||
omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
if (atomic_read(&clkdm->usecount) > 0)
|
||||
_clkdm_add_autodeps(clkdm);
|
||||
|
||||
omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
}
|
||||
|
||||
static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
|
||||
if (atomic_read(&clkdm->usecount) > 0)
|
||||
_clkdm_del_autodeps(clkdm);
|
||||
}
|
||||
|
||||
static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)
|
||||
{
|
||||
bool hwsup = false;
|
||||
|
||||
if (!clkdm->clktrctrl_mask)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The CLKDM_MISSING_IDLE_REPORTING flag documentation has
|
||||
* more details on the unpleasant problem this is working
|
||||
* around
|
||||
*/
|
||||
if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
|
||||
(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
|
||||
omap3xxx_clkdm_wakeup(clkdm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
|
||||
if (hwsup) {
|
||||
/* Disable HW transitions when we are changing deps */
|
||||
omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
_clkdm_add_autodeps(clkdm);
|
||||
omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
} else {
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
|
||||
omap3xxx_clkdm_wakeup(clkdm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)
|
||||
{
|
||||
bool hwsup = false;
|
||||
|
||||
if (!clkdm->clktrctrl_mask)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The CLKDM_MISSING_IDLE_REPORTING flag documentation has
|
||||
* more details on the unpleasant problem this is working
|
||||
* around
|
||||
*/
|
||||
if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
|
||||
!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
|
||||
omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
|
||||
if (hwsup) {
|
||||
/* Disable HW transitions when we are changing deps */
|
||||
omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
_clkdm_del_autodeps(clkdm);
|
||||
omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
|
||||
clkdm->clktrctrl_mask);
|
||||
} else {
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)
|
||||
omap3xxx_clkdm_sleep(clkdm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct clkdm_ops omap3_clkdm_operations = {
|
||||
.clkdm_add_wkdep = omap2_clkdm_add_wkdep,
|
||||
.clkdm_del_wkdep = omap2_clkdm_del_wkdep,
|
||||
.clkdm_read_wkdep = omap2_clkdm_read_wkdep,
|
||||
.clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
|
||||
.clkdm_add_sleepdep = omap3xxx_clkdm_add_sleepdep,
|
||||
.clkdm_del_sleepdep = omap3xxx_clkdm_del_sleepdep,
|
||||
.clkdm_read_sleepdep = omap3xxx_clkdm_read_sleepdep,
|
||||
.clkdm_clear_all_sleepdeps = omap3xxx_clkdm_clear_all_sleepdeps,
|
||||
.clkdm_sleep = omap3xxx_clkdm_sleep,
|
||||
.clkdm_wakeup = omap3xxx_clkdm_wakeup,
|
||||
.clkdm_allow_idle = omap3xxx_clkdm_allow_idle,
|
||||
.clkdm_deny_idle = omap3xxx_clkdm_deny_idle,
|
||||
.clkdm_clk_enable = omap3xxx_clkdm_clk_enable,
|
||||
.clkdm_clk_disable = omap3xxx_clkdm_clk_disable,
|
||||
};
|
||||
|
||||
/*
|
||||
* Context save/restore code - OMAP3 only
|
||||
*/
|
||||
#ifdef CONFIG_ARCH_OMAP3
|
||||
struct omap3_cm_regs {
|
||||
u32 iva2_cm_clksel1;
|
||||
u32 iva2_cm_clksel2;
|
||||
|
@ -555,4 +635,31 @@ void omap3_cm_restore_context(void)
|
|||
omap2_cm_write_mod_reg(cm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
|
||||
OMAP3_CM_CLKOUT_CTRL_OFFSET);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static struct cm_ll_data omap3xxx_cm_ll_data = {
|
||||
.split_idlest_reg = &omap3xxx_cm_split_idlest_reg,
|
||||
.wait_module_ready = &omap3xxx_cm_wait_module_ready,
|
||||
};
|
||||
|
||||
int __init omap3xxx_cm_init(void)
|
||||
{
|
||||
if (!cpu_is_omap34xx())
|
||||
return 0;
|
||||
|
||||
return cm_register(&omap3xxx_cm_ll_data);
|
||||
}
|
||||
|
||||
static void __exit omap3xxx_cm_exit(void)
|
||||
{
|
||||
if (!cpu_is_omap34xx())
|
||||
return;
|
||||
|
||||
/* Should never happen */
|
||||
WARN(cm_unregister(&omap3xxx_cm_ll_data),
|
||||
"%s: cm_ll_data function pointer mismatch\n", __func__);
|
||||
}
|
||||
__exitcall(omap3xxx_cm_exit);
|
91
arch/arm/mach-omap2/cm3xxx.h
Normal file
91
arch/arm/mach-omap2/cm3xxx.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* OMAP2/3 Clock Management (CM) register definitions
|
||||
*
|
||||
* Copyright (C) 2007-2009 Texas Instruments, Inc.
|
||||
* Copyright (C) 2007-2010 Nokia Corporation
|
||||
* Paul Walmsley
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* The CM hardware modules on the OMAP2/3 are quite similar to each
|
||||
* other. The CM modules/instances on OMAP4 are quite different, so
|
||||
* they are handled in a separate file.
|
||||
*/
|
||||
#ifndef __ARCH_ASM_MACH_OMAP2_CM3XXX_H
|
||||
#define __ARCH_ASM_MACH_OMAP2_CM3XXX_H
|
||||
|
||||
#include "prcm-common.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
|
||||
#define OMAP34XX_CM_REGADDR(module, reg) \
|
||||
OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
|
||||
|
||||
|
||||
/*
|
||||
* OMAP3-specific global CM registers
|
||||
* Use cm_{read,write}_reg() with these registers.
|
||||
* These registers appear once per CM module.
|
||||
*/
|
||||
|
||||
#define OMAP3430_CM_REVISION OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000)
|
||||
#define OMAP3430_CM_SYSCONFIG OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010)
|
||||
#define OMAP3430_CM_POLCTRL OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c)
|
||||
|
||||
#define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070
|
||||
#define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
|
||||
|
||||
/*
|
||||
* Module specific CM register offsets from CM_BASE + domain offset
|
||||
* Use cm_{read,write}_mod_reg() with these registers.
|
||||
* These register offsets generally appear in more than one PRCM submodule.
|
||||
*/
|
||||
|
||||
/* OMAP3-specific register offsets */
|
||||
|
||||
#define OMAP3430_CM_CLKEN_PLL 0x0004
|
||||
#define OMAP3430ES2_CM_CLKEN2 0x0004
|
||||
#define OMAP3430ES2_CM_FCLKEN3 0x0008
|
||||
#define OMAP3430_CM_IDLEST_PLL CM_IDLEST2
|
||||
#define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2
|
||||
#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2
|
||||
#define OMAP3430_CM_CLKSEL1 CM_CLKSEL
|
||||
#define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL
|
||||
#define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2
|
||||
#define OMAP3430_CM_SLEEPDEP CM_CLKSEL2
|
||||
#define OMAP3430_CM_CLKSEL3 OMAP2_CM_CLKSTCTRL
|
||||
#define OMAP3430_CM_CLKSTST 0x004c
|
||||
#define OMAP3430ES2_CM_CLKSEL4 0x004c
|
||||
#define OMAP3430ES2_CM_CLKSEL5 0x0050
|
||||
#define OMAP3430_CM_CLKSEL2_EMU 0x0050
|
||||
#define OMAP3430_CM_CLKSEL3_EMU 0x0054
|
||||
|
||||
|
||||
/* CM_IDLEST bit field values to indicate deasserted IdleReq */
|
||||
|
||||
#define OMAP34XX_CM_IDLEST_VAL 1
|
||||
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
|
||||
extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
|
||||
extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
|
||||
extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
|
||||
|
||||
extern bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
|
||||
extern int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
|
||||
u8 idlest_shift);
|
||||
|
||||
extern int omap3xxx_cm_split_idlest_reg(void __iomem *idlest_reg,
|
||||
s16 *prcm_inst, u8 *idlest_reg_id);
|
||||
|
||||
extern void omap3_cm_save_context(void);
|
||||
extern void omap3_cm_restore_context(void);
|
||||
|
||||
extern int __init omap3xxx_cm_init(void);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
139
arch/arm/mach-omap2/cm_common.c
Normal file
139
arch/arm/mach-omap2/cm_common.c
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* OMAP2+ common Clock Management (CM) IP block functions
|
||||
*
|
||||
* Copyright (C) 2012 Texas Instruments, Inc.
|
||||
* Paul Walmsley
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* XXX This code should eventually be moved to a CM driver.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include "cm2xxx.h"
|
||||
#include "cm3xxx.h"
|
||||
#include "cm44xx.h"
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
* cm_ll_data: function pointers to SoC-specific implementations of
|
||||
* common CM functions
|
||||
*/
|
||||
static struct cm_ll_data null_cm_ll_data;
|
||||
static struct cm_ll_data *cm_ll_data = &null_cm_ll_data;
|
||||
|
||||
/* cm_base: base virtual address of the CM IP block */
|
||||
void __iomem *cm_base;
|
||||
|
||||
/* cm2_base: base virtual address of the CM2 IP block (OMAP44xx only) */
|
||||
void __iomem *cm2_base;
|
||||
|
||||
/**
|
||||
* omap2_set_globals_cm - set the CM/CM2 base addresses (for early use)
|
||||
* @cm: CM base virtual address
|
||||
* @cm2: CM2 base virtual address (if present on the booted SoC)
|
||||
*
|
||||
* XXX Will be replaced when the PRM/CM drivers are completed.
|
||||
*/
|
||||
void __init omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2)
|
||||
{
|
||||
cm_base = cm;
|
||||
cm2_base = cm2;
|
||||
}
|
||||
|
||||
/**
|
||||
* cm_split_idlest_reg - split CM_IDLEST reg addr into its components
|
||||
* @idlest_reg: CM_IDLEST* virtual address
|
||||
* @prcm_inst: pointer to an s16 to return the PRCM instance offset
|
||||
* @idlest_reg_id: pointer to a u8 to return the CM_IDLESTx register ID
|
||||
*
|
||||
* Given an absolute CM_IDLEST register address @idlest_reg, passes
|
||||
* the PRCM instance offset and IDLEST register ID back to the caller
|
||||
* via the @prcm_inst and @idlest_reg_id. Returns -EINVAL upon error,
|
||||
* or 0 upon success. XXX This function is only needed until absolute
|
||||
* register addresses are removed from the OMAP struct clk records.
|
||||
*/
|
||||
int cm_split_idlest_reg(void __iomem *idlest_reg, s16 *prcm_inst,
|
||||
u8 *idlest_reg_id)
|
||||
{
|
||||
if (!cm_ll_data->split_idlest_reg) {
|
||||
WARN_ONCE(1, "cm: %s: no low-level function defined\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return cm_ll_data->split_idlest_reg(idlest_reg, prcm_inst,
|
||||
idlest_reg_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* cm_wait_module_ready - wait for a module to leave idle or standby
|
||||
* @prcm_mod: PRCM module offset
|
||||
* @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
|
||||
* @idlest_shift: shift of the bit in the CM_IDLEST* register to check
|
||||
*
|
||||
* Wait for the PRCM to indicate that the module identified by
|
||||
* (@prcm_mod, @idlest_id, @idlest_shift) is clocked. Return 0 upon
|
||||
* success, -EBUSY if the module doesn't enable in time, or -EINVAL if
|
||||
* no per-SoC wait_module_ready() function pointer has been registered
|
||||
* or if the idlest register is unknown on the SoC.
|
||||
*/
|
||||
int cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
|
||||
{
|
||||
if (!cm_ll_data->wait_module_ready) {
|
||||
WARN_ONCE(1, "cm: %s: no low-level function defined\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return cm_ll_data->wait_module_ready(prcm_mod, idlest_id, idlest_shift);
|
||||
}
|
||||
|
||||
/**
|
||||
* cm_register - register per-SoC low-level data with the CM
|
||||
* @cld: low-level per-SoC OMAP CM data & function pointers to register
|
||||
*
|
||||
* Register per-SoC low-level OMAP CM data and function pointers with
|
||||
* the OMAP CM common interface. The caller must keep the data
|
||||
* pointed to by @cld valid until it calls cm_unregister() and
|
||||
* it returns successfully. Returns 0 upon success, -EINVAL if @cld
|
||||
* is NULL, or -EEXIST if cm_register() has already been called
|
||||
* without an intervening cm_unregister().
|
||||
*/
|
||||
int cm_register(struct cm_ll_data *cld)
|
||||
{
|
||||
if (!cld)
|
||||
return -EINVAL;
|
||||
|
||||
if (cm_ll_data != &null_cm_ll_data)
|
||||
return -EEXIST;
|
||||
|
||||
cm_ll_data = cld;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cm_unregister - unregister per-SoC low-level data & function pointers
|
||||
* @cld: low-level per-SoC OMAP CM data & function pointers to unregister
|
||||
*
|
||||
* Unregister per-SoC low-level OMAP CM data and function pointers
|
||||
* that were previously registered with cm_register(). The
|
||||
* caller may not destroy any of the data pointed to by @cld until
|
||||
* this function returns successfully. Returns 0 upon success, or
|
||||
* -EINVAL if @cld is NULL or if @cld does not match the struct
|
||||
* cm_ll_data * previously registered by cm_register().
|
||||
*/
|
||||
int cm_unregister(struct cm_ll_data *cld)
|
||||
{
|
||||
if (!cld || cm_ll_data != cld)
|
||||
return -EINVAL;
|
||||
|
||||
cm_ll_data = &null_cm_ll_data;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -2,8 +2,9 @@
|
|||
* OMAP4 CM instance functions
|
||||
*
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Copyright (C) 2011 Texas Instruments, Inc.
|
||||
* Copyright (C) 2008-2011 Texas Instruments, Inc.
|
||||
* Paul Walmsley
|
||||
* Rajendra Nayak <rnayak@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -22,6 +23,7 @@
|
|||
|
||||
#include "iomap.h"
|
||||
#include "common.h"
|
||||
#include "clockdomain.h"
|
||||
#include "cm.h"
|
||||
#include "cm1_44xx.h"
|
||||
#include "cm2_44xx.h"
|
||||
|
@ -343,3 +345,141 @@ void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
|
|||
v &= ~OMAP4430_MODULEMODE_MASK;
|
||||
omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clockdomain low-level functions
|
||||
*/
|
||||
|
||||
static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
|
||||
clkdm1->prcm_partition,
|
||||
clkdm1->cm_inst, clkdm1->clkdm_offs +
|
||||
OMAP4_CM_STATICDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
|
||||
clkdm1->prcm_partition,
|
||||
clkdm1->cm_inst, clkdm1->clkdm_offs +
|
||||
OMAP4_CM_STATICDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
|
||||
clkdm1->cm_inst,
|
||||
clkdm1->clkdm_offs +
|
||||
OMAP4_CM_STATICDEP,
|
||||
(1 << clkdm2->dep_bit));
|
||||
}
|
||||
|
||||
static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
|
||||
{
|
||||
struct clkdm_dep *cd;
|
||||
u32 mask = 0;
|
||||
|
||||
if (!clkdm->prcm_partition)
|
||||
return 0;
|
||||
|
||||
for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
|
||||
if (!cd->clkdm)
|
||||
continue; /* only happens if data is erroneous */
|
||||
|
||||
mask |= 1 << cd->clkdm->dep_bit;
|
||||
atomic_set(&cd->wkdep_usecount, 0);
|
||||
}
|
||||
|
||||
omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
|
||||
clkdm->cm_inst, clkdm->clkdm_offs +
|
||||
OMAP4_CM_STATICDEP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap4_clkdm_sleep(struct clockdomain *clkdm)
|
||||
{
|
||||
omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
|
||||
clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
|
||||
{
|
||||
omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
|
||||
clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
|
||||
clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
}
|
||||
|
||||
static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
|
||||
omap4_clkdm_wakeup(clkdm);
|
||||
else
|
||||
omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
|
||||
clkdm->cm_inst,
|
||||
clkdm->clkdm_offs);
|
||||
}
|
||||
|
||||
static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
|
||||
{
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
|
||||
return omap4_clkdm_wakeup(clkdm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
|
||||
{
|
||||
bool hwsup = false;
|
||||
|
||||
if (!clkdm->prcm_partition)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The CLKDM_MISSING_IDLE_REPORTING flag documentation has
|
||||
* more details on the unpleasant problem this is working
|
||||
* around
|
||||
*/
|
||||
if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
|
||||
!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
|
||||
omap4_clkdm_allow_idle(clkdm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
|
||||
clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
|
||||
if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
|
||||
omap4_clkdm_sleep(clkdm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct clkdm_ops omap4_clkdm_operations = {
|
||||
.clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep,
|
||||
.clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep,
|
||||
.clkdm_read_wkdep = omap4_clkdm_read_wkup_sleep_dep,
|
||||
.clkdm_clear_all_wkdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
|
||||
.clkdm_add_sleepdep = omap4_clkdm_add_wkup_sleep_dep,
|
||||
.clkdm_del_sleepdep = omap4_clkdm_del_wkup_sleep_dep,
|
||||
.clkdm_read_sleepdep = omap4_clkdm_read_wkup_sleep_dep,
|
||||
.clkdm_clear_all_sleepdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
|
||||
.clkdm_sleep = omap4_clkdm_sleep,
|
||||
.clkdm_wakeup = omap4_clkdm_wakeup,
|
||||
.clkdm_allow_idle = omap4_clkdm_allow_idle,
|
||||
.clkdm_deny_idle = omap4_clkdm_deny_idle,
|
||||
.clkdm_clk_enable = omap4_clkdm_clk_enable,
|
||||
.clkdm_clk_disable = omap4_clkdm_clk_disable,
|
||||
};
|
||||
|
|
|
@ -38,4 +38,6 @@ extern u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst,
|
|||
extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx,
|
||||
u32 mask);
|
||||
|
||||
extern void omap_cm_base_init(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,196 +14,13 @@
|
|||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_data/dsp-omap.h>
|
||||
|
||||
#include <plat/vram.h>
|
||||
|
||||
#include "soc.h"
|
||||
#include "iomap.h"
|
||||
#include "common.h"
|
||||
#include "clock.h"
|
||||
#include "sdrc.h"
|
||||
#include "control.h"
|
||||
#include "omap-secure.h"
|
||||
|
||||
/* Global address base setup code */
|
||||
|
||||
static void __init __omap2_set_globals(struct omap_globals *omap2_globals)
|
||||
{
|
||||
omap2_set_globals_tap(omap2_globals);
|
||||
omap2_set_globals_sdrc(omap2_globals);
|
||||
omap2_set_globals_control(omap2_globals);
|
||||
omap2_set_globals_prcm(omap2_globals);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SOC_OMAP2420)
|
||||
|
||||
static struct omap_globals omap242x_globals = {
|
||||
.class = OMAP242X_CLASS,
|
||||
.tap = OMAP2_L4_IO_ADDRESS(0x48014000),
|
||||
.sdrc = OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE),
|
||||
.sms = OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE),
|
||||
.ctrl = OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE),
|
||||
.prm = OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE),
|
||||
.cm = OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE),
|
||||
};
|
||||
|
||||
void __init omap2_set_globals_242x(void)
|
||||
{
|
||||
__omap2_set_globals(&omap242x_globals);
|
||||
}
|
||||
|
||||
void __init omap242x_map_io(void)
|
||||
{
|
||||
omap242x_map_common_io();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SOC_OMAP2430)
|
||||
|
||||
static struct omap_globals omap243x_globals = {
|
||||
.class = OMAP243X_CLASS,
|
||||
.tap = OMAP2_L4_IO_ADDRESS(0x4900a000),
|
||||
.sdrc = OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE),
|
||||
.sms = OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE),
|
||||
.ctrl = OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE),
|
||||
.prm = OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE),
|
||||
.cm = OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE),
|
||||
};
|
||||
|
||||
void __init omap2_set_globals_243x(void)
|
||||
{
|
||||
__omap2_set_globals(&omap243x_globals);
|
||||
}
|
||||
|
||||
void __init omap243x_map_io(void)
|
||||
{
|
||||
omap243x_map_common_io();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP3)
|
||||
|
||||
static struct omap_globals omap3_globals = {
|
||||
.class = OMAP343X_CLASS,
|
||||
.tap = OMAP2_L4_IO_ADDRESS(0x4830A000),
|
||||
.sdrc = OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE),
|
||||
.sms = OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE),
|
||||
.ctrl = OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE),
|
||||
.prm = OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE),
|
||||
.cm = OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE),
|
||||
};
|
||||
|
||||
void __init omap2_set_globals_3xxx(void)
|
||||
{
|
||||
__omap2_set_globals(&omap3_globals);
|
||||
}
|
||||
|
||||
void __init omap3_map_io(void)
|
||||
{
|
||||
omap34xx_map_common_io();
|
||||
}
|
||||
|
||||
/*
|
||||
* Adjust TAP register base such that omap3_check_revision accesses the correct
|
||||
* TI81XX register for checking device ID (it adds 0x204 to tap base while
|
||||
* TI81XX DEVICE ID register is at offset 0x600 from control base).
|
||||
*/
|
||||
#define TI81XX_TAP_BASE (TI81XX_CTRL_BASE + \
|
||||
TI81XX_CONTROL_DEVICE_ID - 0x204)
|
||||
|
||||
static struct omap_globals ti81xx_globals = {
|
||||
.class = OMAP343X_CLASS,
|
||||
.tap = OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE),
|
||||
.ctrl = OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
|
||||
.prm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE),
|
||||
.cm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE),
|
||||
};
|
||||
|
||||
void __init omap2_set_globals_ti81xx(void)
|
||||
{
|
||||
__omap2_set_globals(&ti81xx_globals);
|
||||
}
|
||||
|
||||
void __init ti81xx_map_io(void)
|
||||
{
|
||||
omapti81xx_map_common_io();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SOC_AM33XX)
|
||||
#define AM33XX_TAP_BASE (AM33XX_CTRL_BASE + \
|
||||
TI81XX_CONTROL_DEVICE_ID - 0x204)
|
||||
|
||||
static struct omap_globals am33xx_globals = {
|
||||
.class = AM335X_CLASS,
|
||||
.tap = AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE),
|
||||
.ctrl = AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE),
|
||||
.prm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE),
|
||||
.cm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE),
|
||||
};
|
||||
|
||||
void __init omap2_set_globals_am33xx(void)
|
||||
{
|
||||
__omap2_set_globals(&am33xx_globals);
|
||||
}
|
||||
|
||||
void __init am33xx_map_io(void)
|
||||
{
|
||||
omapam33xx_map_common_io();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP4)
|
||||
static struct omap_globals omap4_globals = {
|
||||
.class = OMAP443X_CLASS,
|
||||
.tap = OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE),
|
||||
.ctrl = OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE),
|
||||
.ctrl_pad = OMAP2_L4_IO_ADDRESS(OMAP443X_CTRL_BASE),
|
||||
.prm = OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE),
|
||||
.cm = OMAP2_L4_IO_ADDRESS(OMAP4430_CM_BASE),
|
||||
.cm2 = OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE),
|
||||
.prcm_mpu = OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE),
|
||||
};
|
||||
|
||||
void __init omap2_set_globals_443x(void)
|
||||
{
|
||||
__omap2_set_globals(&omap4_globals);
|
||||
}
|
||||
|
||||
void __init omap4_map_io(void)
|
||||
{
|
||||
omap44xx_map_common_io();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SOC_OMAP5)
|
||||
static struct omap_globals omap5_globals = {
|
||||
.class = OMAP54XX_CLASS,
|
||||
.tap = OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE),
|
||||
.ctrl = OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE),
|
||||
.ctrl_pad = OMAP2_L4_IO_ADDRESS(OMAP54XX_CTRL_BASE),
|
||||
.prm = OMAP2_L4_IO_ADDRESS(OMAP54XX_PRM_BASE),
|
||||
.cm = OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_AON_BASE),
|
||||
.cm2 = OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_BASE),
|
||||
.prcm_mpu = OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE),
|
||||
};
|
||||
|
||||
void __init omap2_set_globals_5xxx(void)
|
||||
{
|
||||
omap2_set_globals_tap(&omap5_globals);
|
||||
omap2_set_globals_control(&omap5_globals);
|
||||
omap2_set_globals_prcm(&omap5_globals);
|
||||
}
|
||||
|
||||
void __init omap5_map_io(void)
|
||||
{
|
||||
omap5_map_common_io();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Stub function for OMAP2 so that common files
|
||||
* continue to build when custom builds are used
|
||||
|
|
|
@ -41,54 +41,6 @@
|
|||
|
||||
#define OMAP_INTC_START NR_IRQS
|
||||
|
||||
#ifdef CONFIG_SOC_OMAP2420
|
||||
extern void omap242x_map_common_io(void);
|
||||
#else
|
||||
static inline void omap242x_map_common_io(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_OMAP2430
|
||||
extern void omap243x_map_common_io(void);
|
||||
#else
|
||||
static inline void omap243x_map_common_io(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP3
|
||||
extern void omap34xx_map_common_io(void);
|
||||
#else
|
||||
static inline void omap34xx_map_common_io(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_TI81XX
|
||||
extern void omapti81xx_map_common_io(void);
|
||||
#else
|
||||
static inline void omapti81xx_map_common_io(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_AM33XX
|
||||
extern void omapam33xx_map_common_io(void);
|
||||
#else
|
||||
static inline void omapam33xx_map_common_io(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP4
|
||||
extern void omap44xx_map_common_io(void);
|
||||
#else
|
||||
static inline void omap44xx_map_common_io(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP2)
|
||||
int omap2_pm_init(void);
|
||||
#else
|
||||
|
@ -125,14 +77,6 @@ static inline int omap_mux_late_init(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_OMAP5
|
||||
extern void omap5_map_common_io(void);
|
||||
#else
|
||||
static inline void omap5_map_common_io(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void omap2_init_common_infrastructure(void);
|
||||
|
||||
extern struct sys_timer omap2_timer;
|
||||
|
@ -165,52 +109,43 @@ void am35xx_init_late(void);
|
|||
void ti81xx_init_late(void);
|
||||
void omap4430_init_late(void);
|
||||
int omap2_common_pm_late_init(void);
|
||||
void omap_prcm_restart(char, const char *);
|
||||
|
||||
/*
|
||||
* IO bases for various OMAP processors
|
||||
* Except the tap base, rest all the io bases
|
||||
* listed are physical addresses.
|
||||
*/
|
||||
struct omap_globals {
|
||||
u32 class; /* OMAP class to detect */
|
||||
void __iomem *tap; /* Control module ID code */
|
||||
void __iomem *sdrc; /* SDRAM Controller */
|
||||
void __iomem *sms; /* SDRAM Memory Scheduler */
|
||||
void __iomem *ctrl; /* System Control Module */
|
||||
void __iomem *ctrl_pad; /* PAD Control Module */
|
||||
void __iomem *prm; /* Power and Reset Management */
|
||||
void __iomem *cm; /* Clock Management */
|
||||
void __iomem *cm2;
|
||||
void __iomem *prcm_mpu;
|
||||
};
|
||||
|
||||
void omap2_set_globals_242x(void);
|
||||
void omap2_set_globals_243x(void);
|
||||
void omap2_set_globals_3xxx(void);
|
||||
void omap2_set_globals_443x(void);
|
||||
void omap2_set_globals_5xxx(void);
|
||||
void omap2_set_globals_ti81xx(void);
|
||||
void omap2_set_globals_am33xx(void);
|
||||
|
||||
/* These get called from omap2_set_globals_xxxx(), do not call these */
|
||||
void omap2_set_globals_tap(struct omap_globals *);
|
||||
#if defined(CONFIG_SOC_HAS_OMAP2_SDRC)
|
||||
void omap2_set_globals_sdrc(struct omap_globals *);
|
||||
#if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
|
||||
void omap2xxx_restart(char mode, const char *cmd);
|
||||
#else
|
||||
static inline void omap2_set_globals_sdrc(struct omap_globals *omap2_globals)
|
||||
{ }
|
||||
static inline void omap2xxx_restart(char mode, const char *cmd)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
void omap2_set_globals_control(struct omap_globals *);
|
||||
void omap2_set_globals_prcm(struct omap_globals *);
|
||||
|
||||
void omap242x_map_io(void);
|
||||
void omap243x_map_io(void);
|
||||
void omap3_map_io(void);
|
||||
void am33xx_map_io(void);
|
||||
void omap4_map_io(void);
|
||||
void omap5_map_io(void);
|
||||
void ti81xx_map_io(void);
|
||||
#ifdef CONFIG_ARCH_OMAP3
|
||||
void omap3xxx_restart(char mode, const char *cmd);
|
||||
#else
|
||||
static inline void omap3xxx_restart(char mode, const char *cmd)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
|
||||
void omap44xx_restart(char mode, const char *cmd);
|
||||
#else
|
||||
static inline void omap44xx_restart(char mode, const char *cmd)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This gets called from mach-omap2/io.c, do not call this */
|
||||
void __init omap2_set_globals_tap(u32 class, void __iomem *tap);
|
||||
|
||||
void __init omap242x_map_io(void);
|
||||
void __init omap243x_map_io(void);
|
||||
void __init omap3_map_io(void);
|
||||
void __init am33xx_map_io(void);
|
||||
void __init omap4_map_io(void);
|
||||
void __init omap5_map_io(void);
|
||||
void __init ti81xx_map_io(void);
|
||||
|
||||
/* omap_barriers_init() is OMAP4 only */
|
||||
void omap_barriers_init(void);
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include "common.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
#include "prm-regbits-34xx.h"
|
||||
#include "prm2xxx_3xxx.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
#include "prm3xxx.h"
|
||||
#include "cm3xxx.h"
|
||||
#include "sdrc.h"
|
||||
#include "pm.h"
|
||||
#include "control.h"
|
||||
|
@ -147,13 +147,11 @@ static struct omap3_control_regs control_context;
|
|||
#define OMAP_CTRL_REGADDR(reg) (omap2_ctrl_base + (reg))
|
||||
#define OMAP4_CTRL_PAD_REGADDR(reg) (omap4_ctrl_pad_base + (reg))
|
||||
|
||||
void __init omap2_set_globals_control(struct omap_globals *omap2_globals)
|
||||
void __init omap2_set_globals_control(void __iomem *ctrl,
|
||||
void __iomem *ctrl_pad)
|
||||
{
|
||||
if (omap2_globals->ctrl)
|
||||
omap2_ctrl_base = omap2_globals->ctrl;
|
||||
|
||||
if (omap2_globals->ctrl_pad)
|
||||
omap4_ctrl_pad_base = omap2_globals->ctrl_pad;
|
||||
omap2_ctrl_base = ctrl;
|
||||
omap4_ctrl_pad_base = ctrl_pad;
|
||||
}
|
||||
|
||||
void __iomem *omap_ctrl_base_get(void)
|
||||
|
|
|
@ -201,6 +201,7 @@
|
|||
#define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO 0x249
|
||||
#define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254
|
||||
#define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257
|
||||
#define OMAP44XX_CONTROL_FUSE_CORE_OPP100OV 0x25A
|
||||
|
||||
/* AM35XX only CONTROL_GENERAL register offsets */
|
||||
#define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)
|
||||
|
@ -414,6 +415,8 @@ extern void omap_ctrl_write_dsp_boot_addr(u32 bootaddr);
|
|||
extern void omap_ctrl_write_dsp_boot_mode(u8 bootmode);
|
||||
extern void omap3630_ctrl_disable_rta(void);
|
||||
extern int omap3_ctrl_save_padconf(void);
|
||||
extern void omap2_set_globals_control(void __iomem *ctrl,
|
||||
void __iomem *ctrl_pad);
|
||||
#else
|
||||
#define omap_ctrl_base_get() 0
|
||||
#define omap_ctrl_readb(x) 0
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <linux/export.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
|
||||
#include <plat/prcm.h>
|
||||
#include "powerdomain.h"
|
||||
#include "clockdomain.h"
|
||||
|
||||
|
|
|
@ -646,29 +646,3 @@ static int __init omap2_init_devices(void)
|
|||
return 0;
|
||||
}
|
||||
arch_initcall(omap2_init_devices);
|
||||
|
||||
#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
|
||||
static int __init omap_init_wdt(void)
|
||||
{
|
||||
int id = -1;
|
||||
struct platform_device *pdev;
|
||||
struct omap_hwmod *oh;
|
||||
char *oh_name = "wd_timer2";
|
||||
char *dev_name = "omap_wdt";
|
||||
|
||||
if (!cpu_class_is_omap2() || of_have_populated_dt())
|
||||
return 0;
|
||||
|
||||
oh = omap_hwmod_lookup(oh_name);
|
||||
if (!oh) {
|
||||
pr_err("Could not look up wd_timer%d hwmod\n", id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pdev = omap_device_build(dev_name, id, oh, NULL, 0, NULL, 0, 0);
|
||||
WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
|
||||
dev_name, oh->name);
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(omap_init_wdt);
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "mux.h"
|
||||
#include "control.h"
|
||||
#include "display.h"
|
||||
#include "prm.h"
|
||||
|
||||
#define DISPC_CONTROL 0x0040
|
||||
#define DISPC_CONTROL2 0x0238
|
||||
|
@ -512,7 +513,6 @@ static void dispc_disable_outputs(void)
|
|||
}
|
||||
}
|
||||
|
||||
#define MAX_MODULE_SOFTRESET_WAIT 10000
|
||||
int omap_dss_reset(struct omap_hwmod *oh)
|
||||
{
|
||||
struct omap_hwmod_opt_clk *oc;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/clkdev.h>
|
||||
|
||||
#include "soc.h"
|
||||
#include "clockdomain.h"
|
||||
#include "clock.h"
|
||||
#include "cm2xxx_3xxx.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
|
@ -42,7 +43,7 @@
|
|||
/* Private functions */
|
||||
|
||||
/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
|
||||
static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
|
||||
static void _omap3_dpll_write_clken(struct clk_hw_omap *clk, u8 clken_bits)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
u32 v;
|
||||
|
@ -56,7 +57,7 @@ static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
|
|||
}
|
||||
|
||||
/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
|
||||
static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
|
||||
static int _omap3_wait_dpll_status(struct clk_hw_omap *clk, u8 state)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
int i = 0;
|
||||
|
@ -64,7 +65,7 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
|
|||
const char *clk_name;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
clk_name = __clk_get_name(clk);
|
||||
clk_name = __clk_get_name(clk->hw.clk);
|
||||
|
||||
state <<= __ffs(dd->idlest_mask);
|
||||
|
||||
|
@ -88,7 +89,7 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
|
|||
}
|
||||
|
||||
/* From 3430 TRM ES2 4.7.6.2 */
|
||||
static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
|
||||
static u16 _omap3_dpll_compute_freqsel(struct clk_hw_omap *clk, u8 n)
|
||||
{
|
||||
unsigned long fint;
|
||||
u16 f = 0;
|
||||
|
@ -133,14 +134,14 @@ static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
|
|||
* locked successfully, return 0; if the DPLL did not lock in the time
|
||||
* allotted, or DPLL3 was passed in, return -EINVAL.
|
||||
*/
|
||||
static int _omap3_noncore_dpll_lock(struct clk *clk)
|
||||
static int _omap3_noncore_dpll_lock(struct clk_hw_omap *clk)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
u8 ai;
|
||||
u8 state = 1;
|
||||
int r = 0;
|
||||
|
||||
pr_debug("clock: locking DPLL %s\n", __clk_get_name(clk));
|
||||
pr_debug("clock: locking DPLL %s\n", __clk_get_name(clk->hw.clk));
|
||||
|
||||
dd = clk->dpll_data;
|
||||
state <<= __ffs(dd->idlest_mask);
|
||||
|
@ -178,7 +179,7 @@ static int _omap3_noncore_dpll_lock(struct clk *clk)
|
|||
* DPLL3 was passed in, or the DPLL does not support low-power bypass,
|
||||
* return -EINVAL.
|
||||
*/
|
||||
static int _omap3_noncore_dpll_bypass(struct clk *clk)
|
||||
static int _omap3_noncore_dpll_bypass(struct clk_hw_omap *clk)
|
||||
{
|
||||
int r;
|
||||
u8 ai;
|
||||
|
@ -187,7 +188,7 @@ static int _omap3_noncore_dpll_bypass(struct clk *clk)
|
|||
return -EINVAL;
|
||||
|
||||
pr_debug("clock: configuring DPLL %s for low-power bypass\n",
|
||||
__clk_get_name(clk));
|
||||
__clk_get_name(clk->hw.clk));
|
||||
|
||||
ai = omap3_dpll_autoidle_read(clk);
|
||||
|
||||
|
@ -210,14 +211,14 @@ static int _omap3_noncore_dpll_bypass(struct clk *clk)
|
|||
* code. If DPLL3 was passed in, or the DPLL does not support
|
||||
* low-power stop, return -EINVAL; otherwise, return 0.
|
||||
*/
|
||||
static int _omap3_noncore_dpll_stop(struct clk *clk)
|
||||
static int _omap3_noncore_dpll_stop(struct clk_hw_omap *clk)
|
||||
{
|
||||
u8 ai;
|
||||
|
||||
if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP)))
|
||||
return -EINVAL;
|
||||
|
||||
pr_debug("clock: stopping DPLL %s\n", __clk_get_name(clk));
|
||||
pr_debug("clock: stopping DPLL %s\n", __clk_get_name(clk->hw.clk));
|
||||
|
||||
ai = omap3_dpll_autoidle_read(clk);
|
||||
|
||||
|
@ -241,11 +242,11 @@ static int _omap3_noncore_dpll_stop(struct clk *clk)
|
|||
* XXX This code is not needed for 3430/AM35xx; can it be optimized
|
||||
* out in non-multi-OMAP builds for those chips?
|
||||
*/
|
||||
static void _lookup_dco(struct clk *clk, u8 *dco, u16 m, u8 n)
|
||||
static void _lookup_dco(struct clk_hw_omap *clk, u8 *dco, u16 m, u8 n)
|
||||
{
|
||||
unsigned long fint, clkinp; /* watch out for overflow */
|
||||
|
||||
clkinp = __clk_get_rate(__clk_get_parent(clk));
|
||||
clkinp = __clk_get_rate(__clk_get_parent(clk->hw.clk));
|
||||
fint = (clkinp / n) * m;
|
||||
|
||||
if (fint < 1000000000)
|
||||
|
@ -266,12 +267,12 @@ static void _lookup_dco(struct clk *clk, u8 *dco, u16 m, u8 n)
|
|||
* XXX This code is not needed for 3430/AM35xx; can it be optimized
|
||||
* out in non-multi-OMAP builds for those chips?
|
||||
*/
|
||||
static void _lookup_sddiv(struct clk *clk, u8 *sd_div, u16 m, u8 n)
|
||||
static void _lookup_sddiv(struct clk_hw_omap *clk, u8 *sd_div, u16 m, u8 n)
|
||||
{
|
||||
unsigned long clkinp, sd; /* watch out for overflow */
|
||||
int mod1, mod2;
|
||||
|
||||
clkinp = __clk_get_rate(__clk_get_parent(clk));
|
||||
clkinp = __clk_get_rate(__clk_get_parent(clk->hw.clk));
|
||||
|
||||
/*
|
||||
* target sigma-delta to near 250MHz
|
||||
|
@ -298,7 +299,8 @@ static void _lookup_sddiv(struct clk *clk, u8 *sd_div, u16 m, u8 n)
|
|||
* Program the DPLL with the supplied M, N values, and wait for the DPLL to
|
||||
* lock.. Returns -EINVAL upon error, or 0 upon success.
|
||||
*/
|
||||
static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
|
||||
static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 m, u8 n,
|
||||
u16 freqsel)
|
||||
{
|
||||
struct dpll_data *dd = clk->dpll_data;
|
||||
u8 dco, sd_div;
|
||||
|
@ -355,8 +357,10 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
|
|||
*
|
||||
* Recalculate and propagate the DPLL rate.
|
||||
*/
|
||||
unsigned long omap3_dpll_recalc(struct clk *clk)
|
||||
unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
|
||||
return omap2_get_dpll_rate(clk);
|
||||
}
|
||||
|
||||
|
@ -376,8 +380,9 @@ unsigned long omap3_dpll_recalc(struct clk *clk)
|
|||
* support low-power stop, or if the DPLL took too long to enter
|
||||
* bypass or lock, return -EINVAL; otherwise, return 0.
|
||||
*/
|
||||
int omap3_noncore_dpll_enable(struct clk *clk)
|
||||
int omap3_noncore_dpll_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
int r;
|
||||
struct dpll_data *dd;
|
||||
struct clk *parent;
|
||||
|
@ -386,22 +391,26 @@ int omap3_noncore_dpll_enable(struct clk *clk)
|
|||
if (!dd)
|
||||
return -EINVAL;
|
||||
|
||||
parent = __clk_get_parent(clk);
|
||||
if (clk->clkdm) {
|
||||
r = clkdm_clk_enable(clk->clkdm, hw->clk);
|
||||
if (r) {
|
||||
WARN(1,
|
||||
"%s: could not enable %s's clockdomain %s: %d\n",
|
||||
__func__, __clk_get_name(hw->clk),
|
||||
clk->clkdm->name, r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (__clk_get_rate(clk) == __clk_get_rate(dd->clk_bypass)) {
|
||||
parent = __clk_get_parent(hw->clk);
|
||||
|
||||
if (__clk_get_rate(hw->clk) == __clk_get_rate(dd->clk_bypass)) {
|
||||
WARN_ON(parent != dd->clk_bypass);
|
||||
r = _omap3_noncore_dpll_bypass(clk);
|
||||
} else {
|
||||
WARN_ON(parent != dd->clk_ref);
|
||||
r = _omap3_noncore_dpll_lock(clk);
|
||||
}
|
||||
/*
|
||||
*FIXME: this is dubious - if clk->rate has changed, what about
|
||||
* propagating?
|
||||
*/
|
||||
if (!r)
|
||||
clk->rate = (clk->recalc) ? clk->recalc(clk) :
|
||||
omap2_get_dpll_rate(clk);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -413,9 +422,13 @@ int omap3_noncore_dpll_enable(struct clk *clk)
|
|||
* Instructs a non-CORE DPLL to enter low-power stop. This function is
|
||||
* intended for use in struct clkops. No return value.
|
||||
*/
|
||||
void omap3_noncore_dpll_disable(struct clk *clk)
|
||||
void omap3_noncore_dpll_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
|
||||
_omap3_noncore_dpll_stop(clk);
|
||||
if (clk->clkdm)
|
||||
clkdm_clk_disable(clk->clkdm, hw->clk);
|
||||
}
|
||||
|
||||
|
||||
|
@ -432,80 +445,72 @@ void omap3_noncore_dpll_disable(struct clk *clk)
|
|||
* target rate if it hasn't been done already, then program and lock
|
||||
* the DPLL. Returns -EINVAL upon error, or 0 upon success.
|
||||
*/
|
||||
int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
|
||||
int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
struct clk *new_parent = NULL;
|
||||
unsigned long hw_rate, bypass_rate;
|
||||
u16 freqsel = 0;
|
||||
struct dpll_data *dd;
|
||||
int ret;
|
||||
|
||||
if (!clk || !rate)
|
||||
if (!hw || !rate)
|
||||
return -EINVAL;
|
||||
|
||||
dd = clk->dpll_data;
|
||||
if (!dd)
|
||||
return -EINVAL;
|
||||
|
||||
hw_rate = (clk->recalc) ? clk->recalc(clk) : omap2_get_dpll_rate(clk);
|
||||
if (rate == hw_rate)
|
||||
return 0;
|
||||
__clk_prepare(dd->clk_bypass);
|
||||
clk_enable(dd->clk_bypass);
|
||||
__clk_prepare(dd->clk_ref);
|
||||
clk_enable(dd->clk_ref);
|
||||
|
||||
/*
|
||||
* Ensure both the bypass and ref clocks are enabled prior to
|
||||
* doing anything; we need the bypass clock running to reprogram
|
||||
* the DPLL.
|
||||
*/
|
||||
omap2_clk_enable(dd->clk_bypass);
|
||||
omap2_clk_enable(dd->clk_ref);
|
||||
|
||||
bypass_rate = __clk_get_rate(dd->clk_bypass);
|
||||
if (bypass_rate == rate &&
|
||||
(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
|
||||
pr_debug("clock: %s: set rate: entering bypass.\n", clk->name);
|
||||
if (__clk_get_rate(dd->clk_bypass) == rate &&
|
||||
(dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
|
||||
pr_debug("%s: %s: set rate: entering bypass.\n",
|
||||
__func__, __clk_get_name(hw->clk));
|
||||
|
||||
ret = _omap3_noncore_dpll_bypass(clk);
|
||||
if (!ret)
|
||||
new_parent = dd->clk_bypass;
|
||||
} else {
|
||||
if (dd->last_rounded_rate != rate)
|
||||
rate = clk->round_rate(clk, rate);
|
||||
rate = __clk_round_rate(hw->clk, rate);
|
||||
|
||||
if (dd->last_rounded_rate == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* No freqsel on OMAP4 and OMAP3630 */
|
||||
if (!soc_is_am33xx() && !cpu_is_omap44xx() && !cpu_is_omap3630()) {
|
||||
if (!cpu_is_omap44xx() && !cpu_is_omap3630()) {
|
||||
freqsel = _omap3_dpll_compute_freqsel(clk,
|
||||
dd->last_rounded_n);
|
||||
if (!freqsel)
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
pr_debug("clock: %s: set rate: locking rate to %lu.\n",
|
||||
__clk_get_name(clk), rate);
|
||||
pr_debug("%s: %s: set rate: locking rate to %lu.\n",
|
||||
__func__, __clk_get_name(hw->clk), rate);
|
||||
|
||||
ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
|
||||
dd->last_rounded_n, freqsel);
|
||||
dd->last_rounded_n, freqsel);
|
||||
if (!ret)
|
||||
new_parent = dd->clk_ref;
|
||||
}
|
||||
if (!ret) {
|
||||
/*
|
||||
* Switch the parent clock in the hierarchy, and make sure
|
||||
* that the new parent's usecount is correct. Note: we
|
||||
* enable the new parent before disabling the old to avoid
|
||||
* any unnecessary hardware disable->enable transitions.
|
||||
*/
|
||||
if (clk->usecount) {
|
||||
omap2_clk_enable(new_parent);
|
||||
omap2_clk_disable(clk->parent);
|
||||
}
|
||||
clk_reparent(clk, new_parent);
|
||||
clk->rate = rate;
|
||||
}
|
||||
omap2_clk_disable(dd->clk_ref);
|
||||
omap2_clk_disable(dd->clk_bypass);
|
||||
/*
|
||||
* FIXME - this is all wrong. common code handles reparenting and
|
||||
* migrating prepare/enable counts. dplls should be a multiplexer
|
||||
* clock and this should be a set_parent operation so that all of that
|
||||
* stuff is inherited for free
|
||||
*/
|
||||
|
||||
if (!ret)
|
||||
__clk_reparent(hw->clk, new_parent);
|
||||
|
||||
clk_disable(dd->clk_ref);
|
||||
__clk_unprepare(dd->clk_ref);
|
||||
clk_disable(dd->clk_bypass);
|
||||
__clk_unprepare(dd->clk_bypass);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -520,7 +525,7 @@ int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
|
|||
* -EINVAL if passed a null pointer or if the struct clk does not
|
||||
* appear to refer to a DPLL.
|
||||
*/
|
||||
u32 omap3_dpll_autoidle_read(struct clk *clk)
|
||||
u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
u32 v;
|
||||
|
@ -549,7 +554,7 @@ u32 omap3_dpll_autoidle_read(struct clk *clk)
|
|||
* OMAP3430. The DPLL will enter low-power stop when its downstream
|
||||
* clocks are gated. No return value.
|
||||
*/
|
||||
void omap3_dpll_allow_idle(struct clk *clk)
|
||||
void omap3_dpll_allow_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
u32 v;
|
||||
|
@ -559,11 +564,8 @@ void omap3_dpll_allow_idle(struct clk *clk)
|
|||
|
||||
dd = clk->dpll_data;
|
||||
|
||||
if (!dd->autoidle_reg) {
|
||||
pr_debug("clock: DPLL %s: autoidle not supported\n",
|
||||
__clk_get_name(clk));
|
||||
if (!dd->autoidle_reg)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* REVISIT: CORE DPLL can optionally enter low-power bypass
|
||||
|
@ -583,7 +585,7 @@ void omap3_dpll_allow_idle(struct clk *clk)
|
|||
*
|
||||
* Disable DPLL automatic idle control. No return value.
|
||||
*/
|
||||
void omap3_dpll_deny_idle(struct clk *clk)
|
||||
void omap3_dpll_deny_idle(struct clk_hw_omap *clk)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
u32 v;
|
||||
|
@ -593,11 +595,8 @@ void omap3_dpll_deny_idle(struct clk *clk)
|
|||
|
||||
dd = clk->dpll_data;
|
||||
|
||||
if (!dd->autoidle_reg) {
|
||||
pr_debug("clock: DPLL %s: autoidle not supported\n",
|
||||
__clk_get_name(clk));
|
||||
if (!dd->autoidle_reg)
|
||||
return;
|
||||
}
|
||||
|
||||
v = __raw_readl(dd->autoidle_reg);
|
||||
v &= ~dd->autoidle_mask;
|
||||
|
@ -615,18 +614,25 @@ void omap3_dpll_deny_idle(struct clk *clk)
|
|||
* Using parent clock DPLL data, look up DPLL state. If locked, set our
|
||||
* rate to the dpll_clk * 2; otherwise, just use dpll_clk.
|
||||
*/
|
||||
unsigned long omap3_clkoutx2_recalc(struct clk *clk)
|
||||
unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
unsigned long rate;
|
||||
u32 v;
|
||||
struct clk *pclk;
|
||||
unsigned long parent_rate;
|
||||
struct clk_hw_omap *pclk = NULL;
|
||||
struct clk *parent;
|
||||
|
||||
/* Walk up the parents of clk, looking for a DPLL */
|
||||
pclk = __clk_get_parent(clk);
|
||||
while (pclk && !pclk->dpll_data)
|
||||
pclk = __clk_get_parent(pclk);
|
||||
do {
|
||||
do {
|
||||
parent = __clk_get_parent(hw->clk);
|
||||
hw = __clk_get_hw(parent);
|
||||
} while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC));
|
||||
if (!hw)
|
||||
break;
|
||||
pclk = to_clk_hw_omap(hw);
|
||||
} while (pclk && !pclk->dpll_data);
|
||||
|
||||
/* clk does not have a DPLL as a parent? error in the clock data */
|
||||
if (!pclk) {
|
||||
|
@ -638,7 +644,6 @@ unsigned long omap3_clkoutx2_recalc(struct clk *clk)
|
|||
|
||||
WARN_ON(!dd->enable_mask);
|
||||
|
||||
parent_rate = __clk_get_rate(__clk_get_parent(clk));
|
||||
v = __raw_readl(dd->control_reg) & dd->enable_mask;
|
||||
v >>= __ffs(dd->enable_mask);
|
||||
if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE))
|
||||
|
@ -649,15 +654,7 @@ unsigned long omap3_clkoutx2_recalc(struct clk *clk)
|
|||
}
|
||||
|
||||
/* OMAP3/4 non-CORE DPLL clkops */
|
||||
|
||||
const struct clkops clkops_omap3_noncore_dpll_ops = {
|
||||
.enable = omap3_noncore_dpll_enable,
|
||||
.disable = omap3_noncore_dpll_disable,
|
||||
.allow_idle = omap3_dpll_allow_idle,
|
||||
.deny_idle = omap3_dpll_deny_idle,
|
||||
};
|
||||
|
||||
const struct clkops clkops_omap3_core_dpll_ops = {
|
||||
const struct clk_hw_omap_ops clkhwops_omap3_dpll = {
|
||||
.allow_idle = omap3_dpll_allow_idle,
|
||||
.deny_idle = omap3_dpll_deny_idle,
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "cm-regbits-44xx.h"
|
||||
|
||||
/* Supported only on OMAP4 */
|
||||
int omap4_dpllmx_gatectrl_read(struct clk *clk)
|
||||
int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk)
|
||||
{
|
||||
u32 v;
|
||||
u32 mask;
|
||||
|
@ -40,7 +40,7 @@ int omap4_dpllmx_gatectrl_read(struct clk *clk)
|
|||
return v;
|
||||
}
|
||||
|
||||
void omap4_dpllmx_allow_gatectrl(struct clk *clk)
|
||||
void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk)
|
||||
{
|
||||
u32 v;
|
||||
u32 mask;
|
||||
|
@ -58,7 +58,7 @@ void omap4_dpllmx_allow_gatectrl(struct clk *clk)
|
|||
__raw_writel(v, clk->clksel_reg);
|
||||
}
|
||||
|
||||
void omap4_dpllmx_deny_gatectrl(struct clk *clk)
|
||||
void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk)
|
||||
{
|
||||
u32 v;
|
||||
u32 mask;
|
||||
|
@ -76,9 +76,9 @@ void omap4_dpllmx_deny_gatectrl(struct clk *clk)
|
|||
__raw_writel(v, clk->clksel_reg);
|
||||
}
|
||||
|
||||
const struct clkops clkops_omap4_dpllmx_ops = {
|
||||
const struct clk_hw_omap_ops clkhwops_omap4_dpllmx = {
|
||||
.allow_idle = omap4_dpllmx_allow_gatectrl,
|
||||
.deny_idle = omap4_dpllmx_deny_gatectrl,
|
||||
.deny_idle = omap4_dpllmx_deny_gatectrl,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -90,8 +90,10 @@ const struct clkops clkops_omap4_dpllmx_ops = {
|
|||
* OMAP4 ABE DPLL. Returns the DPLL's output rate (before M-dividers)
|
||||
* upon success, or 0 upon error.
|
||||
*/
|
||||
unsigned long omap4_dpll_regm4xen_recalc(struct clk *clk)
|
||||
unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 v;
|
||||
unsigned long rate;
|
||||
struct dpll_data *dd;
|
||||
|
@ -123,8 +125,11 @@ unsigned long omap4_dpll_regm4xen_recalc(struct clk *clk)
|
|||
* M-dividers) upon success, -EINVAL if @clk is null or not a DPLL, or
|
||||
* ~0 if an error occurred in omap2_dpll_round_rate().
|
||||
*/
|
||||
long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate)
|
||||
long omap4_dpll_regm4xen_round_rate(struct clk_hw *hw,
|
||||
unsigned long target_rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct clk_hw_omap *clk = to_clk_hw_omap(hw);
|
||||
u32 v;
|
||||
struct dpll_data *dd;
|
||||
long r;
|
||||
|
@ -140,7 +145,7 @@ long omap4_dpll_regm4xen_round_rate(struct clk *clk, unsigned long target_rate)
|
|||
if (v)
|
||||
target_rate = target_rate / OMAP4430_REGM4XEN_MULT;
|
||||
|
||||
r = omap2_dpll_round_rate(clk, target_rate);
|
||||
r = omap2_dpll_round_rate(hw, target_rate, NULL);
|
||||
if (r == ~0)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -31,11 +31,9 @@
|
|||
#include "omap_device.h"
|
||||
#include "hdq1w.h"
|
||||
|
||||
#include "prm.h"
|
||||
#include "common.h"
|
||||
|
||||
/* Maximum microseconds to wait for OMAP module to softreset */
|
||||
#define MAX_MODULE_SOFTRESET_WAIT 10000
|
||||
|
||||
/**
|
||||
* omap_hdq1w_reset - reset the OMAP HDQ1W module
|
||||
* @oh: struct omap_hwmod *
|
||||
|
|
|
@ -20,10 +20,11 @@
|
|||
*/
|
||||
|
||||
#include "soc.h"
|
||||
#include "common.h"
|
||||
#include "omap_hwmod.h"
|
||||
#include "omap_device.h"
|
||||
|
||||
#include "prm.h"
|
||||
#include "common.h"
|
||||
#include "mux.h"
|
||||
#include "i2c.h"
|
||||
|
||||
|
@ -32,9 +33,6 @@
|
|||
#define OMAP2_I2C_CON_OFFSET 0x24
|
||||
#define OMAP4_I2C_CON_OFFSET 0xA4
|
||||
|
||||
/* Maximum microseconds to wait for OMAP module to softreset */
|
||||
#define MAX_MODULE_SOFTRESET_WAIT 10000
|
||||
|
||||
#define MAX_OMAP_I2C_HWMOD_NAME_LEN 16
|
||||
|
||||
static void __init omap2_i2c_mux_pins(int bus_id)
|
||||
|
|
|
@ -548,11 +548,12 @@ void __init omap5xxx_check_revision(void)
|
|||
* detect the exact revision later on in omap2_detect_revision() once map_io
|
||||
* is done.
|
||||
*/
|
||||
void __init omap2_set_globals_tap(struct omap_globals *omap2_globals)
|
||||
void __init omap2_set_globals_tap(u32 class, void __iomem *tap)
|
||||
{
|
||||
omap_revision = omap2_globals->class;
|
||||
tap_base = omap2_globals->tap;
|
||||
omap_revision = class;
|
||||
tap_base = tap;
|
||||
|
||||
/* XXX What is this intended to do? */
|
||||
if (cpu_is_omap34xx())
|
||||
tap_prod_id = 0x0210;
|
||||
else
|
||||
|
|
|
@ -40,8 +40,19 @@
|
|||
#include "clock44xx.h"
|
||||
#include "omap-pm.h"
|
||||
#include "sdrc.h"
|
||||
#include "control.h"
|
||||
#include "serial.h"
|
||||
#include "sram.h"
|
||||
#include "cm2xxx.h"
|
||||
#include "cm3xxx.h"
|
||||
#include "prm.h"
|
||||
#include "cm.h"
|
||||
#include "prcm_mpu44xx.h"
|
||||
#include "prminst44xx.h"
|
||||
#include "cminst44xx.h"
|
||||
#include "prm2xxx.h"
|
||||
#include "prm3xxx.h"
|
||||
#include "prm44xx.h"
|
||||
|
||||
/*
|
||||
* The machine specific code may provide the extra mapping besides the
|
||||
|
@ -264,7 +275,7 @@ static struct map_desc omap54xx_io_desc[] __initdata = {
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_OMAP2420
|
||||
void __init omap242x_map_common_io(void)
|
||||
void __init omap242x_map_io(void)
|
||||
{
|
||||
iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
|
||||
iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc));
|
||||
|
@ -272,7 +283,7 @@ void __init omap242x_map_common_io(void)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_OMAP2430
|
||||
void __init omap243x_map_common_io(void)
|
||||
void __init omap243x_map_io(void)
|
||||
{
|
||||
iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
|
||||
iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc));
|
||||
|
@ -280,28 +291,28 @@ void __init omap243x_map_common_io(void)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP3
|
||||
void __init omap34xx_map_common_io(void)
|
||||
void __init omap3_map_io(void)
|
||||
{
|
||||
iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_TI81XX
|
||||
void __init omapti81xx_map_common_io(void)
|
||||
void __init ti81xx_map_io(void)
|
||||
{
|
||||
iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_AM33XX
|
||||
void __init omapam33xx_map_common_io(void)
|
||||
void __init am33xx_map_io(void)
|
||||
{
|
||||
iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP4
|
||||
void __init omap44xx_map_common_io(void)
|
||||
void __init omap4_map_io(void)
|
||||
{
|
||||
iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
|
||||
omap_barriers_init();
|
||||
|
@ -309,7 +320,7 @@ void __init omap44xx_map_common_io(void)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_OMAP5
|
||||
void __init omap5_map_common_io(void)
|
||||
void __init omap5_map_io(void)
|
||||
{
|
||||
iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc));
|
||||
}
|
||||
|
@ -371,8 +382,16 @@ static void __init omap_hwmod_init_postsetup(void)
|
|||
#ifdef CONFIG_SOC_OMAP2420
|
||||
void __init omap2420_init_early(void)
|
||||
{
|
||||
omap2_set_globals_242x();
|
||||
omap2_set_globals_tap(OMAP242X_CLASS, OMAP2_L4_IO_ADDRESS(0x48014000));
|
||||
omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE),
|
||||
OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE));
|
||||
omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE),
|
||||
NULL);
|
||||
omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE));
|
||||
omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE), NULL);
|
||||
omap2xxx_check_revision();
|
||||
omap2xxx_prm_init();
|
||||
omap2xxx_cm_init();
|
||||
omap2xxx_voltagedomains_init();
|
||||
omap242x_powerdomains_init();
|
||||
omap242x_clockdomains_init();
|
||||
|
@ -386,14 +405,23 @@ void __init omap2420_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap2_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_OMAP2430
|
||||
void __init omap2430_init_early(void)
|
||||
{
|
||||
omap2_set_globals_243x();
|
||||
omap2_set_globals_tap(OMAP243X_CLASS, OMAP2_L4_IO_ADDRESS(0x4900a000));
|
||||
omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE),
|
||||
OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE));
|
||||
omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE),
|
||||
NULL);
|
||||
omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE));
|
||||
omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE), NULL);
|
||||
omap2xxx_check_revision();
|
||||
omap2xxx_prm_init();
|
||||
omap2xxx_cm_init();
|
||||
omap2xxx_voltagedomains_init();
|
||||
omap243x_powerdomains_init();
|
||||
omap243x_clockdomains_init();
|
||||
|
@ -407,6 +435,7 @@ void __init omap2430_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap2_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -417,9 +446,17 @@ void __init omap2430_init_late(void)
|
|||
#ifdef CONFIG_ARCH_OMAP3
|
||||
void __init omap3_init_early(void)
|
||||
{
|
||||
omap2_set_globals_3xxx();
|
||||
omap2_set_globals_tap(OMAP343X_CLASS, OMAP2_L4_IO_ADDRESS(0x4830A000));
|
||||
omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE),
|
||||
OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE));
|
||||
omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE),
|
||||
NULL);
|
||||
omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE));
|
||||
omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), NULL);
|
||||
omap3xxx_check_revision();
|
||||
omap3xxx_check_features();
|
||||
omap3xxx_prm_init();
|
||||
omap3xxx_cm_init();
|
||||
omap3xxx_voltagedomains_init();
|
||||
omap3xxx_powerdomains_init();
|
||||
omap3xxx_clockdomains_init();
|
||||
|
@ -450,7 +487,12 @@ void __init am35xx_init_early(void)
|
|||
|
||||
void __init ti81xx_init_early(void)
|
||||
{
|
||||
omap2_set_globals_ti81xx();
|
||||
omap2_set_globals_tap(OMAP343X_CLASS,
|
||||
OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE));
|
||||
omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
|
||||
NULL);
|
||||
omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE));
|
||||
omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), NULL);
|
||||
omap3xxx_check_revision();
|
||||
ti81xx_check_features();
|
||||
omap3xxx_voltagedomains_init();
|
||||
|
@ -466,6 +508,7 @@ void __init omap3_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap3_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
|
||||
void __init omap3430_init_late(void)
|
||||
|
@ -473,6 +516,7 @@ void __init omap3430_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap3_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
|
||||
void __init omap35xx_init_late(void)
|
||||
|
@ -480,6 +524,7 @@ void __init omap35xx_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap3_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
|
||||
void __init omap3630_init_late(void)
|
||||
|
@ -487,6 +532,7 @@ void __init omap3630_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap3_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
|
||||
void __init am35xx_init_late(void)
|
||||
|
@ -494,6 +540,7 @@ void __init am35xx_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap3_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
|
||||
void __init ti81xx_init_late(void)
|
||||
|
@ -501,13 +548,19 @@ void __init ti81xx_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap3_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_AM33XX
|
||||
void __init am33xx_init_early(void)
|
||||
{
|
||||
omap2_set_globals_am33xx();
|
||||
omap2_set_globals_tap(AM335X_CLASS,
|
||||
AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE));
|
||||
omap2_set_globals_control(AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE),
|
||||
NULL);
|
||||
omap2_set_globals_prm(AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE));
|
||||
omap2_set_globals_cm(AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), NULL);
|
||||
omap3xxx_check_revision();
|
||||
ti81xx_check_features();
|
||||
am33xx_voltagedomains_init();
|
||||
|
@ -522,9 +575,19 @@ void __init am33xx_init_early(void)
|
|||
#ifdef CONFIG_ARCH_OMAP4
|
||||
void __init omap4430_init_early(void)
|
||||
{
|
||||
omap2_set_globals_443x();
|
||||
omap2_set_globals_tap(OMAP443X_CLASS,
|
||||
OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE));
|
||||
omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE),
|
||||
OMAP2_L4_IO_ADDRESS(OMAP443X_CTRL_BASE));
|
||||
omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE));
|
||||
omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP4430_CM_BASE),
|
||||
OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE));
|
||||
omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE));
|
||||
omap_prm_base_init();
|
||||
omap_cm_base_init();
|
||||
omap4xxx_check_revision();
|
||||
omap4xxx_check_features();
|
||||
omap44xx_prm_init();
|
||||
omap44xx_voltagedomains_init();
|
||||
omap44xx_powerdomains_init();
|
||||
omap44xx_clockdomains_init();
|
||||
|
@ -538,13 +601,23 @@ void __init omap4430_init_late(void)
|
|||
omap_mux_late_init();
|
||||
omap2_common_pm_late_init();
|
||||
omap4_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SOC_OMAP5
|
||||
void __init omap5_init_early(void)
|
||||
{
|
||||
omap2_set_globals_5xxx();
|
||||
omap2_set_globals_tap(OMAP54XX_CLASS,
|
||||
OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE));
|
||||
omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE),
|
||||
OMAP2_L4_IO_ADDRESS(OMAP54XX_CTRL_BASE));
|
||||
omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRM_BASE));
|
||||
omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_AON_BASE),
|
||||
OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_BASE));
|
||||
omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
|
||||
omap_prm_base_init();
|
||||
omap_cm_base_init();
|
||||
omap5xxx_check_revision();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
* FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle.
|
||||
* Sidetone needs non-gated ICLK and sidetone autoidle is broken.
|
||||
*/
|
||||
#include "cm2xxx_3xxx.h"
|
||||
#include "cm3xxx.h"
|
||||
#include "cm-regbits-34xx.h"
|
||||
|
||||
static int omap3_enable_st_clock(unsigned int id, bool enable)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/platform_data/gpio-omap.h>
|
||||
|
||||
#include "prm.h"
|
||||
#include "common.h"
|
||||
#include "control.h"
|
||||
#include "omap_hwmod.h"
|
||||
|
@ -43,9 +44,6 @@
|
|||
#define MSDI_CON_CLKD_MASK (0x3f << 0)
|
||||
#define MSDI_CON_CLKD_SHIFT 0
|
||||
|
||||
/* Maximum microseconds to wait for OMAP module to softreset */
|
||||
#define MAX_MODULE_SOFTRESET_WAIT 10000
|
||||
|
||||
/* MSDI_TARGET_RESET_CLKD: clock divisor to use throughout the reset */
|
||||
#define MSDI_TARGET_RESET_CLKD 0x3ff
|
||||
|
||||
|
|
65
arch/arm/mach-omap2/omap2-restart.c
Normal file
65
arch/arm/mach-omap2/omap2-restart.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* omap2-restart.c - code common to all OMAP2xxx machines.
|
||||
*
|
||||
* Copyright (C) 2012 Texas Instruments
|
||||
* Paul Walmsley
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "prm2xxx.h"
|
||||
|
||||
/*
|
||||
* reset_virt_prcm_set_ck, reset_sys_ck: pointers to the virt_prcm_set
|
||||
* clock and the sys_ck. Used during the reset process
|
||||
*/
|
||||
static struct clk *reset_virt_prcm_set_ck, *reset_sys_ck;
|
||||
|
||||
/* Reboot handling */
|
||||
|
||||
/**
|
||||
* omap2xxx_restart - Set DPLL to bypass mode for reboot to work
|
||||
*
|
||||
* Set the DPLL to bypass so that reboot completes successfully. No
|
||||
* return value.
|
||||
*/
|
||||
void omap2xxx_restart(char mode, const char *cmd)
|
||||
{
|
||||
u32 rate;
|
||||
|
||||
rate = clk_get_rate(reset_sys_ck);
|
||||
clk_set_rate(reset_virt_prcm_set_ck, rate);
|
||||
|
||||
/* XXX Should save the cmd argument for use after the reboot */
|
||||
|
||||
omap2xxx_prm_dpll_reset(); /* never returns */
|
||||
while (1);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap2xxx_common_look_up_clks_for_reset - look up clocks needed for restart
|
||||
*
|
||||
* Some clocks need to be looked up in advance for the SoC restart
|
||||
* operation to work - see omap2xxx_restart(). Returns -EINVAL upon
|
||||
* error or 0 upon success.
|
||||
*/
|
||||
static int __init omap2xxx_common_look_up_clks_for_reset(void)
|
||||
{
|
||||
reset_virt_prcm_set_ck = clk_get(NULL, "virt_prcm_set");
|
||||
if (IS_ERR(reset_virt_prcm_set_ck))
|
||||
return -EINVAL;
|
||||
|
||||
reset_sys_ck = clk_get(NULL, "sys_ck");
|
||||
if (IS_ERR(reset_sys_ck))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
core_initcall(omap2xxx_common_look_up_clks_for_reset);
|
36
arch/arm/mach-omap2/omap3-restart.c
Normal file
36
arch/arm/mach-omap2/omap3-restart.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* omap3-restart.c - Code common to all OMAP3xxx machines.
|
||||
*
|
||||
* Copyright (C) 2009, 2012 Texas Instruments
|
||||
* Copyright (C) 2010 Nokia Corporation
|
||||
* Tony Lindgren <tony@atomide.com>
|
||||
* Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include "iomap.h"
|
||||
#include "common.h"
|
||||
#include "control.h"
|
||||
#include "prm3xxx.h"
|
||||
|
||||
/* Global address base setup code */
|
||||
|
||||
/**
|
||||
* omap3xxx_restart - trigger a software restart of the SoC
|
||||
* @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
|
||||
* @cmd: passed from the userspace program rebooting the system (if provided)
|
||||
*
|
||||
* Resets the SoC. For @cmd, see the 'reboot' syscall in
|
||||
* kernel/sys.c. No return value.
|
||||
*/
|
||||
void omap3xxx_restart(char mode, const char *cmd)
|
||||
{
|
||||
omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0));
|
||||
omap3xxx_prm_dpll3_reset(); /* never returns */
|
||||
while (1);
|
||||
}
|
|
@ -27,9 +27,12 @@
|
|||
|
||||
#include "omap-wakeupgen.h"
|
||||
#include "soc.h"
|
||||
#include "iomap.h"
|
||||
#include "common.h"
|
||||
#include "mmc.h"
|
||||
#include "hsmmc.h"
|
||||
#include "prminst44xx.h"
|
||||
#include "prcm_mpu44xx.h"
|
||||
#include "omap4-sar-layout.h"
|
||||
#include "omap-secure.h"
|
||||
#include "sram.h"
|
||||
|
@ -279,3 +282,19 @@ int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* omap44xx_restart - trigger a software restart of the SoC
|
||||
* @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
|
||||
* @cmd: passed from the userspace program rebooting the system (if provided)
|
||||
*
|
||||
* Resets the SoC. For @cmd, see the 'reboot' syscall in
|
||||
* kernel/sys.c. No return value.
|
||||
*/
|
||||
void omap44xx_restart(char mode, const char *cmd)
|
||||
{
|
||||
/* XXX Should save 'cmd' into scratchpad for use after reboot */
|
||||
omap4_prminst_global_warm_sw_reset(); /* never returns */
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
|
|
@ -441,19 +441,21 @@ int omap_device_get_context_loss_count(struct platform_device *pdev)
|
|||
/**
|
||||
* omap_device_count_resources - count number of struct resource entries needed
|
||||
* @od: struct omap_device *
|
||||
* @flags: Type of resources to include when counting (IRQ/DMA/MEM)
|
||||
*
|
||||
* Count the number of struct resource entries needed for this
|
||||
* omap_device @od. Used by omap_device_build_ss() to determine how
|
||||
* much memory to allocate before calling
|
||||
* omap_device_fill_resources(). Returns the count.
|
||||
*/
|
||||
static int omap_device_count_resources(struct omap_device *od)
|
||||
static int omap_device_count_resources(struct omap_device *od,
|
||||
unsigned long flags)
|
||||
{
|
||||
int c = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < od->hwmods_cnt; i++)
|
||||
c += omap_hwmod_count_resources(od->hwmods[i]);
|
||||
c += omap_hwmod_count_resources(od->hwmods[i], flags);
|
||||
|
||||
pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n",
|
||||
od->pdev->name, c, od->hwmods_cnt);
|
||||
|
@ -557,52 +559,73 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,
|
|||
od->hwmods = hwmods;
|
||||
od->pdev = pdev;
|
||||
|
||||
res_count = omap_device_count_resources(od);
|
||||
/*
|
||||
* Non-DT Boot:
|
||||
* Here, pdev->num_resources = 0, and we should get all the
|
||||
* resources from hwmod.
|
||||
*
|
||||
* DT Boot:
|
||||
* OF framework will construct the resource structure (currently
|
||||
* does for MEM & IRQ resource) and we should respect/use these
|
||||
* resources, killing hwmod dependency.
|
||||
* If pdev->num_resources > 0, we assume that MEM & IRQ resources
|
||||
* have been allocated by OF layer already (through DTB).
|
||||
*
|
||||
* Non-DT Boot:
|
||||
* Here, pdev->num_resources = 0, and we should get all the
|
||||
* resources from hwmod.
|
||||
* As preparation for the future we examine the OF provided resources
|
||||
* to see if we have DMA resources provided already. In this case
|
||||
* there is no need to update the resources for the device, we use the
|
||||
* OF provided ones.
|
||||
*
|
||||
* TODO: Once DMA resource is available from OF layer, we should
|
||||
* kill filling any resources from hwmod.
|
||||
*/
|
||||
if (res_count > pdev->num_resources) {
|
||||
/* Allocate resources memory to account for new resources */
|
||||
res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
|
||||
if (!res)
|
||||
goto oda_exit3;
|
||||
if (!pdev->num_resources) {
|
||||
/* Count all resources for the device */
|
||||
res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
|
||||
IORESOURCE_DMA |
|
||||
IORESOURCE_MEM);
|
||||
} else {
|
||||
/* Take a look if we already have DMA resource via DT */
|
||||
for (i = 0; i < pdev->num_resources; i++) {
|
||||
struct resource *r = &pdev->resource[i];
|
||||
|
||||
/*
|
||||
* If pdev->num_resources > 0, then assume that,
|
||||
* MEM and IRQ resources will only come from DT and only
|
||||
* fill DMA resource from hwmod layer.
|
||||
*/
|
||||
if (pdev->num_resources && pdev->resource) {
|
||||
dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n",
|
||||
__func__, res_count);
|
||||
memcpy(res, pdev->resource,
|
||||
sizeof(struct resource) * pdev->num_resources);
|
||||
_od_fill_dma_resources(od, &res[pdev->num_resources]);
|
||||
} else {
|
||||
dev_dbg(&pdev->dev, "%s(): using resources from hwmod %d\n",
|
||||
__func__, res_count);
|
||||
omap_device_fill_resources(od, res);
|
||||
/* We have it, no need to touch the resources */
|
||||
if (r->flags == IORESOURCE_DMA)
|
||||
goto have_everything;
|
||||
}
|
||||
/* Count only DMA resources for the device */
|
||||
res_count = omap_device_count_resources(od, IORESOURCE_DMA);
|
||||
/* The device has no DMA resource, no need for update */
|
||||
if (!res_count)
|
||||
goto have_everything;
|
||||
|
||||
ret = platform_device_add_resources(pdev, res, res_count);
|
||||
kfree(res);
|
||||
|
||||
if (ret)
|
||||
goto oda_exit3;
|
||||
res_count += pdev->num_resources;
|
||||
}
|
||||
|
||||
/* Allocate resources memory to account for new resources */
|
||||
res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
|
||||
if (!res)
|
||||
goto oda_exit3;
|
||||
|
||||
if (!pdev->num_resources) {
|
||||
dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n",
|
||||
__func__, res_count);
|
||||
omap_device_fill_resources(od, res);
|
||||
} else {
|
||||
dev_dbg(&pdev->dev,
|
||||
"%s: appending %d DMA resources from hwmod\n",
|
||||
__func__, res_count - pdev->num_resources);
|
||||
memcpy(res, pdev->resource,
|
||||
sizeof(struct resource) * pdev->num_resources);
|
||||
_od_fill_dma_resources(od, &res[pdev->num_resources]);
|
||||
}
|
||||
|
||||
ret = platform_device_add_resources(pdev, res, res_count);
|
||||
kfree(res);
|
||||
|
||||
if (ret)
|
||||
goto oda_exit3;
|
||||
|
||||
have_everything:
|
||||
if (!pm_lats) {
|
||||
pm_lats = omap_default_latency;
|
||||
pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue