1 /* 2 * arch/arm/plat-omap/include/mach/clockdomain.h 3 * 4 * OMAP2/3 clockdomain framework functions 5 * 6 * Copyright (C) 2008 Texas Instruments, Inc. 7 * Copyright (C) 2008-2010 Nokia Corporation 8 * 9 * Paul Walmsley 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 */ 15 16 #ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H 17 #define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H 18 19 #include <linux/init.h> 20 21 #include "powerdomain.h" 22 #include <plat/clock.h> 23 #include <plat/cpu.h> 24 25 /* Clockdomain capability flags */ 26 #define CLKDM_CAN_FORCE_SLEEP (1 << 0) 27 #define CLKDM_CAN_FORCE_WAKEUP (1 << 1) 28 #define CLKDM_CAN_ENABLE_AUTO (1 << 2) 29 #define CLKDM_CAN_DISABLE_AUTO (1 << 3) 30 31 #define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO) 32 #define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP) 33 #define CLKDM_CAN_HWSUP_SWSUP (CLKDM_CAN_SWSUP | CLKDM_CAN_HWSUP) 34 35 /** 36 * struct clkdm_autodep - clkdm deps to add when entering/exiting hwsup mode 37 * @clkdm: clockdomain to add wkdep+sleepdep on - set name member only 38 * @omap_chip: OMAP chip types that this autodep is valid on 39 * 40 * A clockdomain that should have wkdeps and sleepdeps added when a 41 * clockdomain should stay active in hwsup mode; and conversely, 42 * removed when the clockdomain should be allowed to go inactive in 43 * hwsup mode. 44 * 45 * Autodeps are deprecated and should be removed after 46 * omap_hwmod-based fine-grained module idle control is added. 47 */ 48 struct clkdm_autodep { 49 union { 50 const char *name; 51 struct clockdomain *ptr; 52 } clkdm; 53 const struct omap_chip_id omap_chip; 54 }; 55 56 /** 57 * struct clkdm_dep - encode dependencies between clockdomains 58 * @clkdm_name: clockdomain name 59 * @clkdm: pointer to the struct clockdomain of @clkdm_name 60 * @omap_chip: OMAP chip types that this dependency is valid on 61 * @wkdep_usecount: Number of wakeup dependencies causing this clkdm to wake 62 * @sleepdep_usecount: Number of sleep deps that could prevent clkdm from idle 63 * 64 * Statically defined. @clkdm is resolved from @clkdm_name at runtime and 65 * should not be pre-initialized. 66 * 67 * XXX Should also include hardware (fixed) dependencies. 68 */ 69 struct clkdm_dep { 70 const char *clkdm_name; 71 struct clockdomain *clkdm; 72 atomic_t wkdep_usecount; 73 atomic_t sleepdep_usecount; 74 const struct omap_chip_id omap_chip; 75 }; 76 77 /** 78 * struct clockdomain - OMAP clockdomain 79 * @name: clockdomain name 80 * @pwrdm: powerdomain containing this clockdomain 81 * @clktrctrl_reg: CLKSTCTRL reg for the given clock domain 82 * @clktrctrl_mask: CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg 83 * @flags: Clockdomain capability flags 84 * @dep_bit: Bit shift of this clockdomain's PM_WKDEP/CM_SLEEPDEP bit 85 * @prcm_partition: (OMAP4 only) PRCM partition ID for this clkdm's registers 86 * @cm_inst: (OMAP4 only) CM instance register offset 87 * @clkdm_offs: (OMAP4 only) CM clockdomain register offset 88 * @wkdep_srcs: Clockdomains that can be told to wake this powerdomain up 89 * @sleepdep_srcs: Clockdomains that can be told to keep this clkdm from inact 90 * @omap_chip: OMAP chip types that this clockdomain is valid on 91 * @usecount: Usecount tracking 92 * @node: list_head to link all clockdomains together 93 * 94 * @prcm_partition should be a macro from mach-omap2/prcm44xx.h (OMAP4 only) 95 * @cm_inst should be a macro ending in _INST from the OMAP4 CM instance 96 * definitions (OMAP4 only) 97 * @clkdm_offs should be a macro ending in _CDOFFS from the OMAP4 CM instance 98 * definitions (OMAP4 only) 99 */ 100 struct clockdomain { 101 const char *name; 102 union { 103 const char *name; 104 struct powerdomain *ptr; 105 } pwrdm; 106 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) 107 const u16 clktrctrl_mask; 108 #endif 109 const u8 flags; 110 const u8 dep_bit; 111 const u8 prcm_partition; 112 const s16 cm_inst; 113 const u16 clkdm_offs; 114 struct clkdm_dep *wkdep_srcs; 115 struct clkdm_dep *sleepdep_srcs; 116 const struct omap_chip_id omap_chip; 117 atomic_t usecount; 118 struct list_head node; 119 }; 120 121 void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps); 122 struct clockdomain *clkdm_lookup(const char *name); 123 124 int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user), 125 void *user); 126 struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm); 127 128 int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); 129 int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); 130 int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); 131 int clkdm_clear_all_wkdeps(struct clockdomain *clkdm); 132 int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); 133 int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); 134 int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2); 135 int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm); 136 137 void omap2_clkdm_allow_idle(struct clockdomain *clkdm); 138 void omap2_clkdm_deny_idle(struct clockdomain *clkdm); 139 140 int omap2_clkdm_wakeup(struct clockdomain *clkdm); 141 int omap2_clkdm_sleep(struct clockdomain *clkdm); 142 143 int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); 144 int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); 145 146 extern void __init omap2_clockdomains_init(void); 147 extern void __init omap44xx_clockdomains_init(void); 148 149 #endif 150