diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-01 20:11:00 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-01 20:11:00 -0700 |
commit | 952414505f55afe5cd6dc004765076aa22b3ed7e (patch) | |
tree | eba11ed702ae02fea7f1a0d422346454fc98296f /arch/arm/mach-omap2/clockdomains3xxx_data.c | |
parent | 68e24ba70465b82ad24e0774ceab5360180d4627 (diff) | |
parent | 3e965b176341b78620f7404fd8b7f9a0d061f8a2 (diff) | |
download | op-kernel-dev-952414505f55afe5cd6dc004765076aa22b3ed7e.zip op-kernel-dev-952414505f55afe5cd6dc004765076aa22b3ed7e.tar.gz |
Merge branch 'next/cleanup' of git://git.linaro.org/people/arnd/arm-soc
* 'next/cleanup' of git://git.linaro.org/people/arnd/arm-soc: (125 commits)
ARM: mach-mxs: fix machines' initializers order
mmc: mxcmmc: explicitly includes mach/hardware.h
arm/imx: explicitly includes mach/hardware.h in pm-imx27.c
arm/imx: remove mx27_setup_weimcs() from mx27.h
arm/imx: explicitly includes mach/hardware.h in mach-kzm_arm11_01.c
arm/imx: remove mx31_setup_weimcs() from mx31.h
ARM: tegra: devices.c should include devices.h
ARM: tegra: cpu-tegra: unexport two functions
ARM: tegra: cpu-tegra: sparse type fix
ARM: tegra: dma: staticify some tables and functions
ARM: tegra: tegra2_clocks: don't export some tables
ARM: tegra: tegra_powergate_is_powered should be static
ARM: tegra: tegra_rtc_read_ms should be static
ARM: tegra: tegra_init_cache should be static
ARM: tegra: pcie: 0 -> NULL changes
ARM: tegra: pcie: include board.h
ARM: tegra: pcie: don't cast __iomem pointers
ARM: tegra: tegra2_clocks: 0 -> NULL changes
ARM: tegra: tegra2_clocks: don't cast __iomem pointers
ARM: tegra: timer: don't cast __iomem pointers
...
Fix up trivial conflicts in
arch/arm/mach-omap2/Makefile,
arch/arm/mach-u300/{Makefile.boot,core.c}
arch/arm/plat-{mxc,omap}/devices.c
Diffstat (limited to 'arch/arm/mach-omap2/clockdomains3xxx_data.c')
-rw-r--r-- | arch/arm/mach-omap2/clockdomains3xxx_data.c | 398 |
1 files changed, 398 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c new file mode 100644 index 0000000..b84e138 --- /dev/null +++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c @@ -0,0 +1,398 @@ +/* + * OMAP3xxx clockdomains + * + * Copyright (C) 2008-2011 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation + * + * Paul Walmsley, Jouni Högander + * + * This file contains clockdomains and clockdomain wakeup/sleep + * dependencies for the OMAP3xxx chips. Some notes: + * + * A useful validation rule for struct clockdomain: Any clockdomain + * referenced by a wkdep_srcs or sleepdep_srcs array must have a + * dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really just + * software-controllable dependencies. Non-software-controllable + * dependencies do exist, but they are not encoded below (yet). + * + * The overly-specific dep_bit names are due to a bit name collision + * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift + * value are the same for all powerdomains: 2 + * + * XXX should dep_bit be a mask, so we can test to see if it is 0 as a + * sanity check? + * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE + */ + +/* + * To-Do List + * -> Port the Sleep/Wakeup dependencies for the domains + * from the Power domain framework + */ + +#include <linux/kernel.h> +#include <linux/io.h> + +#include "clockdomain.h" +#include "prm2xxx_3xxx.h" +#include "cm2xxx_3xxx.h" +#include "cm-regbits-34xx.h" +#include "prm-regbits-34xx.h" + +/* + * Clockdomain dependencies for wkdeps/sleepdeps + * + * XXX Hardware dependencies (e.g., dependencies that cannot be + * changed in software) are not included here yet, but should be. + */ + +/* OMAP3-specific possible dependencies */ + +/* + * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE + * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE + */ +static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = { + { .clkdm_name = "iva2_clkdm", }, + { .clkdm_name = "mpu_clkdm", }, + { .clkdm_name = "wkup_clkdm", }, + { NULL }, +}; + +/* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */ +static struct clkdm_dep per_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "iva2_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +/* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */ +static struct clkdm_dep usbhost_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "iva2_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +/* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */ +static struct clkdm_dep mpu_3xxx_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "iva2_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "per_clkdm" }, + { NULL }, +}; + +/* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */ +static struct clkdm_dep iva2_wkdeps[] = { + { .clkdm_name = "core_l3_clkdm" }, + { .clkdm_name = "core_l4_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { .clkdm_name = "dss_clkdm" }, + { .clkdm_name = "per_clkdm" }, + { NULL }, +}; + +/* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */ +static struct clkdm_dep cam_wkdeps[] = { + { .clkdm_name = "iva2_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +/* 3430 PM_WKDEP_DSS: IVA2, MPU, WKUP */ +static struct clkdm_dep dss_wkdeps[] = { + { .clkdm_name = "iva2_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, + { NULL }, +}; + +/* 3430: PM_WKDEP_NEON: MPU */ +static struct clkdm_dep neon_wkdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { NULL }, +}; + +/* Sleep dependency source arrays for OMAP3-specific clkdms */ + +/* 3430: CM_SLEEPDEP_DSS: MPU, IVA */ +static struct clkdm_dep dss_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "iva2_clkdm" }, + { NULL }, +}; + +/* 3430: CM_SLEEPDEP_PER: MPU, IVA */ +static struct clkdm_dep per_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "iva2_clkdm" }, + { NULL }, +}; + +/* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */ +static struct clkdm_dep usbhost_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "iva2_clkdm" }, + { NULL }, +}; + +/* 3430: CM_SLEEPDEP_CAM: MPU */ +static struct clkdm_dep cam_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { NULL }, +}; + +/* + * 3430ES1: CM_SLEEPDEP_GFX: MPU + * 3430ES2: CM_SLEEPDEP_SGX: MPU + * These can share data since they will never be present simultaneously + * on the same device. + */ +static struct clkdm_dep gfx_sgx_sleepdeps[] = { + { .clkdm_name = "mpu_clkdm" }, + { NULL }, +}; + +/* + * OMAP3 clockdomains + */ + +static struct clockdomain mpu_3xxx_clkdm = { + .name = "mpu_clkdm", + .pwrdm = { .name = "mpu_pwrdm" }, + .flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP, + .dep_bit = OMAP3430_EN_MPU_SHIFT, + .wkdep_srcs = mpu_3xxx_wkdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK, +}; + +static struct clockdomain neon_clkdm = { + .name = "neon_clkdm", + .pwrdm = { .name = "neon_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = neon_wkdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK, +}; + +static struct clockdomain iva2_clkdm = { + .name = "iva2_clkdm", + .pwrdm = { .name = "iva2_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT, + .wkdep_srcs = iva2_wkdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK, +}; + +static struct clockdomain gfx_3430es1_clkdm = { + .name = "gfx_clkdm", + .pwrdm = { .name = "gfx_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = gfx_sgx_3xxx_wkdeps, + .sleepdep_srcs = gfx_sgx_sleepdeps, + .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK, +}; + +static struct clockdomain sgx_clkdm = { + .name = "sgx_clkdm", + .pwrdm = { .name = "sgx_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = gfx_sgx_3xxx_wkdeps, + .sleepdep_srcs = gfx_sgx_sleepdeps, + .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK, +}; + +/* + * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but + * then that information was removed from the 34xx ES2+ TRM. It is + * unclear whether the core is still there, but the clockdomain logic + * is there, and must be programmed to an appropriate state if the + * CORE clockdomain is to become inactive. + */ +static struct clockdomain d2d_clkdm = { + .name = "d2d_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK, +}; + +/* + * XXX add usecounting for clkdm dependencies, otherwise the presence + * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm + * could cause trouble + */ +static struct clockdomain core_l3_3xxx_clkdm = { + .name = "core_l3_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP, + .dep_bit = OMAP3430_EN_CORE_SHIFT, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK, +}; + +/* + * XXX add usecounting for clkdm dependencies, otherwise the presence + * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm + * could cause trouble + */ +static struct clockdomain core_l4_3xxx_clkdm = { + .name = "core_l4_clkdm", + .pwrdm = { .name = "core_pwrdm" }, + .flags = CLKDM_CAN_HWSUP, + .dep_bit = OMAP3430_EN_CORE_SHIFT, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK, +}; + +/* Another case of bit name collisions between several registers: EN_DSS */ +static struct clockdomain dss_3xxx_clkdm = { + .name = "dss_clkdm", + .pwrdm = { .name = "dss_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT, + .wkdep_srcs = dss_wkdeps, + .sleepdep_srcs = dss_sleepdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK, +}; + +static struct clockdomain cam_clkdm = { + .name = "cam_clkdm", + .pwrdm = { .name = "cam_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = cam_wkdeps, + .sleepdep_srcs = cam_sleepdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK, +}; + +static struct clockdomain usbhost_clkdm = { + .name = "usbhost_clkdm", + .pwrdm = { .name = "usbhost_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .wkdep_srcs = usbhost_wkdeps, + .sleepdep_srcs = usbhost_sleepdeps, + .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK, +}; + +static struct clockdomain per_clkdm = { + .name = "per_clkdm", + .pwrdm = { .name = "per_pwrdm" }, + .flags = CLKDM_CAN_HWSUP_SWSUP, + .dep_bit = OMAP3430_EN_PER_SHIFT, + .wkdep_srcs = per_wkdeps, + .sleepdep_srcs = per_sleepdeps, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK, +}; + +/* + * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is + * switched of even if sdti is in use + */ +static struct clockdomain emu_clkdm = { + .name = "emu_clkdm", + .pwrdm = { .name = "emu_pwrdm" }, + .flags = /* CLKDM_CAN_ENABLE_AUTO | */CLKDM_CAN_SWSUP, + .clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK, +}; + +static struct clockdomain dpll1_clkdm = { + .name = "dpll1_clkdm", + .pwrdm = { .name = "dpll1_pwrdm" }, +}; + +static struct clockdomain dpll2_clkdm = { + .name = "dpll2_clkdm", + .pwrdm = { .name = "dpll2_pwrdm" }, +}; + +static struct clockdomain dpll3_clkdm = { + .name = "dpll3_clkdm", + .pwrdm = { .name = "dpll3_pwrdm" }, +}; + +static struct clockdomain dpll4_clkdm = { + .name = "dpll4_clkdm", + .pwrdm = { .name = "dpll4_pwrdm" }, +}; + +static struct clockdomain dpll5_clkdm = { + .name = "dpll5_clkdm", + .pwrdm = { .name = "dpll5_pwrdm" }, +}; + +/* + * Clockdomain hwsup dependencies + */ + +static struct clkdm_autodep clkdm_autodeps[] = { + { + .clkdm = { .name = "mpu_clkdm" }, + }, + { + .clkdm = { .name = "iva2_clkdm" }, + }, + { + .clkdm = { .name = NULL }, + } +}; + +/* + * + */ + +static struct clockdomain *clockdomains_omap3430_common[] __initdata = { + &wkup_common_clkdm, + &cm_common_clkdm, + &prm_common_clkdm, + &mpu_3xxx_clkdm, + &neon_clkdm, + &iva2_clkdm, + &d2d_clkdm, + &core_l3_3xxx_clkdm, + &core_l4_3xxx_clkdm, + &dss_3xxx_clkdm, + &cam_clkdm, + &per_clkdm, + &emu_clkdm, + &dpll1_clkdm, + &dpll2_clkdm, + &dpll3_clkdm, + &dpll4_clkdm, + NULL +}; + +static struct clockdomain *clockdomains_omap3430es1[] __initdata = { + &gfx_3430es1_clkdm, + NULL, +}; + +static struct clockdomain *clockdomains_omap3430es2plus[] __initdata = { + &sgx_clkdm, + &dpll5_clkdm, + &usbhost_clkdm, + NULL, +}; + +void __init omap3xxx_clockdomains_init(void) +{ + struct clockdomain **sc; + + if (!cpu_is_omap34xx()) + return; + + clkdm_register_platform_funcs(&omap3_clkdm_operations); + clkdm_register_clkdms(clockdomains_omap3430_common); + + sc = (omap_rev() == OMAP3430_REV_ES1_0) ? clockdomains_omap3430es1 : + clockdomains_omap3430es2plus; + + clkdm_register_clkdms(sc); + + clkdm_register_autodeps(clkdm_autodeps); + clkdm_complete_init(); +} |