1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * TI clock autoidle support 4 * 5 * Copyright (C) 2013 Texas Instruments, Inc. 6 * 7 * Tero Kristo <t-kristo@ti.com> 8 */ 9 10 #include <linux/clk-provider.h> 11 #include <linux/slab.h> 12 #include <linux/io.h> 13 #include <linux/of.h> 14 #include <linux/of_address.h> 15 #include <linux/clk/ti.h> 16 17 #include "clock.h" 18 19 struct clk_ti_autoidle { 20 struct clk_omap_reg reg; 21 u8 shift; 22 u8 flags; 23 const char *name; 24 struct list_head node; 25 }; 26 27 #define AUTOIDLE_LOW 0x1 28 29 static LIST_HEAD(autoidle_clks); 30 31 /* 32 * we have some non-atomic read/write 33 * operations behind it, so lets 34 * take one lock for handling autoidle 35 * of all clocks 36 */ 37 static DEFINE_SPINLOCK(autoidle_spinlock); 38 39 static int _omap2_clk_deny_idle(struct clk_hw_omap *clk) 40 { 41 if (clk->ops && clk->ops->deny_idle) { 42 unsigned long irqflags; 43 44 spin_lock_irqsave(&autoidle_spinlock, irqflags); 45 clk->autoidle_count++; 46 if (clk->autoidle_count == 1) 47 clk->ops->deny_idle(clk); 48 49 spin_unlock_irqrestore(&autoidle_spinlock, irqflags); 50 } 51 return 0; 52 } 53 54 static int _omap2_clk_allow_idle(struct clk_hw_omap *clk) 55 { 56 if (clk->ops && clk->ops->allow_idle) { 57 unsigned long irqflags; 58 59 spin_lock_irqsave(&autoidle_spinlock, irqflags); 60 clk->autoidle_count--; 61 if (clk->autoidle_count == 0) 62 clk->ops->allow_idle(clk); 63 64 spin_unlock_irqrestore(&autoidle_spinlock, irqflags); 65 } 66 return 0; 67 } 68 69 /** 70 * omap2_clk_deny_idle - disable autoidle on an OMAP clock 71 * @clk: struct clk * to disable autoidle for 72 * 73 * Disable autoidle on an OMAP clock. 74 */ 75 int omap2_clk_deny_idle(struct clk *clk) 76 { 77 struct clk_hw *hw; 78 79 if (!clk) 80 return -EINVAL; 81 82 hw = __clk_get_hw(clk); 83 84 if (omap2_clk_is_hw_omap(hw)) { 85 struct clk_hw_omap *c = to_clk_hw_omap(hw); 86 87 return _omap2_clk_deny_idle(c); 88 } 89 90 return -EINVAL; 91 } 92 93 /** 94 * omap2_clk_allow_idle - enable autoidle on an OMAP clock 95 * @clk: struct clk * to enable autoidle for 96 * 97 * Enable autoidle on an OMAP clock. 98 */ 99 int omap2_clk_allow_idle(struct clk *clk) 100 { 101 struct clk_hw *hw; 102 103 if (!clk) 104 return -EINVAL; 105 106 hw = __clk_get_hw(clk); 107 108 if (omap2_clk_is_hw_omap(hw)) { 109 struct clk_hw_omap *c = to_clk_hw_omap(hw); 110 111 return _omap2_clk_allow_idle(c); 112 } 113 114 return -EINVAL; 115 } 116 117 static void _allow_autoidle(struct clk_ti_autoidle *clk) 118 { 119 u32 val; 120 121 val = ti_clk_ll_ops->clk_readl(&clk->reg); 122 123 if (clk->flags & AUTOIDLE_LOW) 124 val &= ~(1 << clk->shift); 125 else 126 val |= (1 << clk->shift); 127 128 ti_clk_ll_ops->clk_writel(val, &clk->reg); 129 } 130 131 static void _deny_autoidle(struct clk_ti_autoidle *clk) 132 { 133 u32 val; 134 135 val = ti_clk_ll_ops->clk_readl(&clk->reg); 136 137 if (clk->flags & AUTOIDLE_LOW) 138 val |= (1 << clk->shift); 139 else 140 val &= ~(1 << clk->shift); 141 142 ti_clk_ll_ops->clk_writel(val, &clk->reg); 143 } 144 145 /** 146 * _clk_generic_allow_autoidle_all - enable autoidle for all clocks 147 * 148 * Enables hardware autoidle for all registered DT clocks, which have 149 * the feature. 150 */ 151 static void _clk_generic_allow_autoidle_all(void) 152 { 153 struct clk_ti_autoidle *c; 154 155 list_for_each_entry(c, &autoidle_clks, node) 156 _allow_autoidle(c); 157 } 158 159 /** 160 * _clk_generic_deny_autoidle_all - disable autoidle for all clocks 161 * 162 * Disables hardware autoidle for all registered DT clocks, which have 163 * the feature. 164 */ 165 static void _clk_generic_deny_autoidle_all(void) 166 { 167 struct clk_ti_autoidle *c; 168 169 list_for_each_entry(c, &autoidle_clks, node) 170 _deny_autoidle(c); 171 } 172 173 /** 174 * of_ti_clk_autoidle_setup - sets up hardware autoidle for a clock 175 * @node: pointer to the clock device node 176 * 177 * Checks if a clock has hardware autoidle support or not (check 178 * for presence of 'ti,autoidle-shift' property in the device tree 179 * node) and sets up the hardware autoidle feature for the clock 180 * if available. If autoidle is available, the clock is also added 181 * to the autoidle list for later processing. Returns 0 on success, 182 * negative error value on failure. 183 */ 184 int __init of_ti_clk_autoidle_setup(struct device_node *node) 185 { 186 u32 shift; 187 struct clk_ti_autoidle *clk; 188 int ret; 189 190 /* Check if this clock has autoidle support or not */ 191 if (of_property_read_u32(node, "ti,autoidle-shift", &shift)) 192 return 0; 193 194 clk = kzalloc(sizeof(*clk), GFP_KERNEL); 195 196 if (!clk) 197 return -ENOMEM; 198 199 clk->shift = shift; 200 clk->name = ti_dt_clk_name(node); 201 ret = ti_clk_get_reg_addr(node, 0, &clk->reg); 202 if (ret) { 203 kfree(clk); 204 return ret; 205 } 206 207 if (of_property_read_bool(node, "ti,invert-autoidle-bit")) 208 clk->flags |= AUTOIDLE_LOW; 209 210 list_add(&clk->node, &autoidle_clks); 211 212 return 0; 213 } 214 215 /** 216 * omap2_clk_enable_autoidle_all - enable autoidle on all OMAP clocks that 217 * support it 218 * 219 * Enable clock autoidle on all OMAP clocks that have allow_idle 220 * function pointers associated with them. This function is intended 221 * to be temporary until support for this is added to the common clock 222 * code. Returns 0. 223 */ 224 int omap2_clk_enable_autoidle_all(void) 225 { 226 int ret; 227 228 ret = omap2_clk_for_each(_omap2_clk_allow_idle); 229 if (ret) 230 return ret; 231 232 _clk_generic_allow_autoidle_all(); 233 234 return 0; 235 } 236 237 /** 238 * omap2_clk_disable_autoidle_all - disable autoidle on all OMAP clocks that 239 * support it 240 * 241 * Disable clock autoidle on all OMAP clocks that have allow_idle 242 * function pointers associated with them. This function is intended 243 * to be temporary until support for this is added to the common clock 244 * code. Returns 0. 245 */ 246 int omap2_clk_disable_autoidle_all(void) 247 { 248 int ret; 249 250 ret = omap2_clk_for_each(_omap2_clk_deny_idle); 251 if (ret) 252 return ret; 253 254 _clk_generic_deny_autoidle_all(); 255 256 return 0; 257 } 258