Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 1 | /* |
| 2 | * OMAP3 Clock init |
| 3 | * |
| 4 | * Copyright (C) 2013 Texas Instruments, Inc |
| 5 | * Tero Kristo (t-kristo@ti.com) |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU General Public License as |
| 9 | * published by the Free Software Foundation version 2. |
| 10 | * |
| 11 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any |
| 12 | * kind, whether express or implied; without even the implied warranty |
| 13 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. |
| 15 | */ |
| 16 | |
| 17 | #include <linux/kernel.h> |
| 18 | #include <linux/list.h> |
Stephen Boyd | 1b29e60 | 2015-06-19 15:00:46 -0700 | [diff] [blame] | 19 | #include <linux/clk.h> |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 20 | #include <linux/clk-provider.h> |
| 21 | #include <linux/clk/ti.h> |
| 22 | |
Tero Kristo | a5aa8a6 | 2015-03-03 10:51:01 +0200 | [diff] [blame] | 23 | #include "clock.h" |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 24 | |
Tero Kristo | 0565fb1 | 2015-03-03 13:27:48 +0200 | [diff] [blame] | 25 | /* |
| 26 | * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks |
| 27 | * that are sourced by DPLL5, and both of these require this clock |
| 28 | * to be at 120 MHz for proper operation. |
| 29 | */ |
| 30 | #define DPLL5_FREQ_FOR_USBHOST 120000000 |
| 31 | |
Tero Kristo | f2671d5 | 2015-03-03 17:28:12 +0200 | [diff] [blame] | 32 | #define OMAP3430ES2_ST_DSS_IDLE_SHIFT 1 |
| 33 | #define OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT 5 |
| 34 | #define OMAP3430ES2_ST_SSI_IDLE_SHIFT 8 |
| 35 | |
| 36 | #define OMAP34XX_CM_IDLEST_VAL 1 |
| 37 | |
Tero Kristo | c9a58b0 | 2015-03-03 21:19:25 +0200 | [diff] [blame] | 38 | /* |
| 39 | * In AM35xx IPSS, the {ICK,FCK} enable bits for modules are exported |
| 40 | * in the same register at a bit offset of 0x8. The EN_ACK for ICK is |
| 41 | * at an offset of 4 from ICK enable bit. |
| 42 | */ |
| 43 | #define AM35XX_IPSS_ICK_MASK 0xF |
| 44 | #define AM35XX_IPSS_ICK_EN_ACK_OFFSET 0x4 |
| 45 | #define AM35XX_IPSS_ICK_FCK_OFFSET 0x8 |
| 46 | #define AM35XX_IPSS_CLK_IDLEST_VAL 0 |
| 47 | |
| 48 | #define AM35XX_ST_IPSS_SHIFT 5 |
| 49 | |
Tero Kristo | f2671d5 | 2015-03-03 17:28:12 +0200 | [diff] [blame] | 50 | /** |
| 51 | * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI |
| 52 | * @clk: struct clk * being enabled |
| 53 | * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into |
| 54 | * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into |
| 55 | * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator |
| 56 | * |
| 57 | * The OMAP3430ES2 SSI target CM_IDLEST bit is at a different shift |
| 58 | * from the CM_{I,F}CLKEN bit. Pass back the correct info via |
| 59 | * @idlest_reg and @idlest_bit. No return value. |
| 60 | */ |
| 61 | static void omap3430es2_clk_ssi_find_idlest(struct clk_hw_omap *clk, |
| 62 | void __iomem **idlest_reg, |
| 63 | u8 *idlest_bit, |
| 64 | u8 *idlest_val) |
| 65 | { |
| 66 | u32 r; |
| 67 | |
| 68 | r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); |
| 69 | *idlest_reg = (__force void __iomem *)r; |
| 70 | *idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT; |
| 71 | *idlest_val = OMAP34XX_CM_IDLEST_VAL; |
| 72 | } |
| 73 | |
Tero Kristo | f2671d5 | 2015-03-03 17:28:12 +0200 | [diff] [blame] | 74 | const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait = { |
| 75 | .allow_idle = omap2_clkt_iclk_allow_idle, |
| 76 | .deny_idle = omap2_clkt_iclk_deny_idle, |
| 77 | .find_idlest = omap3430es2_clk_ssi_find_idlest, |
| 78 | .find_companion = omap2_clk_dflt_find_companion, |
| 79 | }; |
| 80 | |
| 81 | /** |
| 82 | * omap3430es2_clk_dss_usbhost_find_idlest - CM_IDLEST info for DSS, USBHOST |
| 83 | * @clk: struct clk * being enabled |
| 84 | * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into |
| 85 | * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into |
| 86 | * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator |
| 87 | * |
| 88 | * Some OMAP modules on OMAP3 ES2+ chips have both initiator and |
| 89 | * target IDLEST bits. For our purposes, we are concerned with the |
| 90 | * target IDLEST bits, which exist at a different bit position than |
| 91 | * the *CLKEN bit position for these modules (DSS and USBHOST) (The |
| 92 | * default find_idlest code assumes that they are at the same |
| 93 | * position.) No return value. |
| 94 | */ |
| 95 | static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk_hw_omap *clk, |
| 96 | void __iomem **idlest_reg, |
| 97 | u8 *idlest_bit, |
| 98 | u8 *idlest_val) |
| 99 | { |
| 100 | u32 r; |
| 101 | |
| 102 | r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); |
| 103 | *idlest_reg = (__force void __iomem *)r; |
| 104 | /* USBHOST_IDLE has same shift */ |
| 105 | *idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT; |
| 106 | *idlest_val = OMAP34XX_CM_IDLEST_VAL; |
| 107 | } |
| 108 | |
| 109 | const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait = { |
| 110 | .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest, |
| 111 | .find_companion = omap2_clk_dflt_find_companion, |
| 112 | }; |
| 113 | |
| 114 | const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait = { |
| 115 | .allow_idle = omap2_clkt_iclk_allow_idle, |
| 116 | .deny_idle = omap2_clkt_iclk_deny_idle, |
| 117 | .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest, |
| 118 | .find_companion = omap2_clk_dflt_find_companion, |
| 119 | }; |
| 120 | |
| 121 | /** |
| 122 | * omap3430es2_clk_hsotgusb_find_idlest - return CM_IDLEST info for HSOTGUSB |
| 123 | * @clk: struct clk * being enabled |
| 124 | * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into |
| 125 | * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into |
| 126 | * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator |
| 127 | * |
| 128 | * The OMAP3430ES2 HSOTGUSB target CM_IDLEST bit is at a different |
| 129 | * shift from the CM_{I,F}CLKEN bit. Pass back the correct info via |
| 130 | * @idlest_reg and @idlest_bit. No return value. |
| 131 | */ |
| 132 | static void omap3430es2_clk_hsotgusb_find_idlest(struct clk_hw_omap *clk, |
| 133 | void __iomem **idlest_reg, |
| 134 | u8 *idlest_bit, |
| 135 | u8 *idlest_val) |
| 136 | { |
| 137 | u32 r; |
| 138 | |
| 139 | r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); |
| 140 | *idlest_reg = (__force void __iomem *)r; |
| 141 | *idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT; |
| 142 | *idlest_val = OMAP34XX_CM_IDLEST_VAL; |
| 143 | } |
| 144 | |
| 145 | const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait = { |
| 146 | .allow_idle = omap2_clkt_iclk_allow_idle, |
| 147 | .deny_idle = omap2_clkt_iclk_deny_idle, |
| 148 | .find_idlest = omap3430es2_clk_hsotgusb_find_idlest, |
| 149 | .find_companion = omap2_clk_dflt_find_companion, |
| 150 | }; |
| 151 | |
Tero Kristo | c9a58b0 | 2015-03-03 21:19:25 +0200 | [diff] [blame] | 152 | /** |
| 153 | * am35xx_clk_find_idlest - return clock ACK info for AM35XX IPSS |
| 154 | * @clk: struct clk * being enabled |
| 155 | * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into |
| 156 | * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into |
| 157 | * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator |
| 158 | * |
| 159 | * The interface clocks on AM35xx IPSS reflects the clock idle status |
| 160 | * in the enable register itsel at a bit offset of 4 from the enable |
| 161 | * bit. A value of 1 indicates that clock is enabled. |
| 162 | */ |
| 163 | static void am35xx_clk_find_idlest(struct clk_hw_omap *clk, |
| 164 | void __iomem **idlest_reg, |
| 165 | u8 *idlest_bit, |
| 166 | u8 *idlest_val) |
| 167 | { |
| 168 | *idlest_reg = (__force void __iomem *)(clk->enable_reg); |
| 169 | *idlest_bit = clk->enable_bit + AM35XX_IPSS_ICK_EN_ACK_OFFSET; |
| 170 | *idlest_val = AM35XX_IPSS_CLK_IDLEST_VAL; |
| 171 | } |
| 172 | |
| 173 | /** |
| 174 | * am35xx_clk_find_companion - find companion clock to @clk |
| 175 | * @clk: struct clk * to find the companion clock of |
| 176 | * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in |
| 177 | * @other_bit: u8 ** to return the companion clock bit shift in |
| 178 | * |
| 179 | * Some clocks don't have companion clocks. For example, modules with |
| 180 | * only an interface clock (such as HECC) don't have a companion |
| 181 | * clock. Right now, this code relies on the hardware exporting a bit |
| 182 | * in the correct companion register that indicates that the |
| 183 | * nonexistent 'companion clock' is active. Future patches will |
| 184 | * associate this type of code with per-module data structures to |
| 185 | * avoid this issue, and remove the casts. No return value. |
| 186 | */ |
| 187 | static void am35xx_clk_find_companion(struct clk_hw_omap *clk, |
| 188 | void __iomem **other_reg, |
| 189 | u8 *other_bit) |
| 190 | { |
| 191 | *other_reg = (__force void __iomem *)(clk->enable_reg); |
| 192 | if (clk->enable_bit & AM35XX_IPSS_ICK_MASK) |
| 193 | *other_bit = clk->enable_bit + AM35XX_IPSS_ICK_FCK_OFFSET; |
| 194 | else |
| 195 | *other_bit = clk->enable_bit - AM35XX_IPSS_ICK_FCK_OFFSET; |
| 196 | } |
| 197 | |
| 198 | const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait = { |
| 199 | .find_idlest = am35xx_clk_find_idlest, |
| 200 | .find_companion = am35xx_clk_find_companion, |
| 201 | }; |
| 202 | |
| 203 | /** |
| 204 | * am35xx_clk_ipss_find_idlest - return CM_IDLEST info for IPSS |
| 205 | * @clk: struct clk * being enabled |
| 206 | * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into |
| 207 | * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into |
| 208 | * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator |
| 209 | * |
| 210 | * The IPSS target CM_IDLEST bit is at a different shift from the |
| 211 | * CM_{I,F}CLKEN bit. Pass back the correct info via @idlest_reg |
| 212 | * and @idlest_bit. No return value. |
| 213 | */ |
| 214 | static void am35xx_clk_ipss_find_idlest(struct clk_hw_omap *clk, |
| 215 | void __iomem **idlest_reg, |
| 216 | u8 *idlest_bit, |
| 217 | u8 *idlest_val) |
| 218 | { |
| 219 | u32 r; |
| 220 | |
| 221 | r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); |
| 222 | *idlest_reg = (__force void __iomem *)r; |
| 223 | *idlest_bit = AM35XX_ST_IPSS_SHIFT; |
| 224 | *idlest_val = OMAP34XX_CM_IDLEST_VAL; |
| 225 | } |
| 226 | |
| 227 | const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait = { |
| 228 | .allow_idle = omap2_clkt_iclk_allow_idle, |
| 229 | .deny_idle = omap2_clkt_iclk_deny_idle, |
| 230 | .find_idlest = am35xx_clk_ipss_find_idlest, |
| 231 | .find_companion = omap2_clk_dflt_find_companion, |
| 232 | }; |
| 233 | |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 234 | static struct ti_dt_clk omap3xxx_clks[] = { |
| 235 | DT_CLK(NULL, "apb_pclk", "dummy_apb_pclk"), |
| 236 | DT_CLK(NULL, "omap_32k_fck", "omap_32k_fck"), |
| 237 | DT_CLK(NULL, "virt_12m_ck", "virt_12m_ck"), |
| 238 | DT_CLK(NULL, "virt_13m_ck", "virt_13m_ck"), |
| 239 | DT_CLK(NULL, "virt_19200000_ck", "virt_19200000_ck"), |
| 240 | DT_CLK(NULL, "virt_26000000_ck", "virt_26000000_ck"), |
| 241 | DT_CLK(NULL, "virt_38_4m_ck", "virt_38_4m_ck"), |
| 242 | DT_CLK(NULL, "osc_sys_ck", "osc_sys_ck"), |
| 243 | DT_CLK("twl", "fck", "osc_sys_ck"), |
| 244 | DT_CLK(NULL, "sys_ck", "sys_ck"), |
| 245 | DT_CLK(NULL, "omap_96m_alwon_fck", "omap_96m_alwon_fck"), |
| 246 | DT_CLK("etb", "emu_core_alwon_ck", "emu_core_alwon_ck"), |
| 247 | DT_CLK(NULL, "sys_altclk", "sys_altclk"), |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 248 | DT_CLK(NULL, "sys_clkout1", "sys_clkout1"), |
| 249 | DT_CLK(NULL, "dpll1_ck", "dpll1_ck"), |
| 250 | DT_CLK(NULL, "dpll1_x2_ck", "dpll1_x2_ck"), |
| 251 | DT_CLK(NULL, "dpll1_x2m2_ck", "dpll1_x2m2_ck"), |
| 252 | DT_CLK(NULL, "dpll3_ck", "dpll3_ck"), |
| 253 | DT_CLK(NULL, "core_ck", "core_ck"), |
| 254 | DT_CLK(NULL, "dpll3_x2_ck", "dpll3_x2_ck"), |
| 255 | DT_CLK(NULL, "dpll3_m2_ck", "dpll3_m2_ck"), |
| 256 | DT_CLK(NULL, "dpll3_m2x2_ck", "dpll3_m2x2_ck"), |
| 257 | DT_CLK(NULL, "dpll3_m3_ck", "dpll3_m3_ck"), |
| 258 | DT_CLK(NULL, "dpll3_m3x2_ck", "dpll3_m3x2_ck"), |
| 259 | DT_CLK(NULL, "dpll4_ck", "dpll4_ck"), |
| 260 | DT_CLK(NULL, "dpll4_x2_ck", "dpll4_x2_ck"), |
| 261 | DT_CLK(NULL, "omap_96m_fck", "omap_96m_fck"), |
| 262 | DT_CLK(NULL, "cm_96m_fck", "cm_96m_fck"), |
| 263 | DT_CLK(NULL, "omap_54m_fck", "omap_54m_fck"), |
| 264 | DT_CLK(NULL, "omap_48m_fck", "omap_48m_fck"), |
| 265 | DT_CLK(NULL, "omap_12m_fck", "omap_12m_fck"), |
| 266 | DT_CLK(NULL, "dpll4_m2_ck", "dpll4_m2_ck"), |
| 267 | DT_CLK(NULL, "dpll4_m2x2_ck", "dpll4_m2x2_ck"), |
| 268 | DT_CLK(NULL, "dpll4_m3_ck", "dpll4_m3_ck"), |
| 269 | DT_CLK(NULL, "dpll4_m3x2_ck", "dpll4_m3x2_ck"), |
| 270 | DT_CLK(NULL, "dpll4_m4_ck", "dpll4_m4_ck"), |
| 271 | DT_CLK(NULL, "dpll4_m4x2_ck", "dpll4_m4x2_ck"), |
| 272 | DT_CLK(NULL, "dpll4_m5_ck", "dpll4_m5_ck"), |
| 273 | DT_CLK(NULL, "dpll4_m5x2_ck", "dpll4_m5x2_ck"), |
| 274 | DT_CLK(NULL, "dpll4_m6_ck", "dpll4_m6_ck"), |
| 275 | DT_CLK(NULL, "dpll4_m6x2_ck", "dpll4_m6x2_ck"), |
| 276 | DT_CLK("etb", "emu_per_alwon_ck", "emu_per_alwon_ck"), |
| 277 | DT_CLK(NULL, "clkout2_src_ck", "clkout2_src_ck"), |
| 278 | DT_CLK(NULL, "sys_clkout2", "sys_clkout2"), |
| 279 | DT_CLK(NULL, "corex2_fck", "corex2_fck"), |
| 280 | DT_CLK(NULL, "dpll1_fck", "dpll1_fck"), |
| 281 | DT_CLK(NULL, "mpu_ck", "mpu_ck"), |
| 282 | DT_CLK(NULL, "arm_fck", "arm_fck"), |
| 283 | DT_CLK("etb", "emu_mpu_alwon_ck", "emu_mpu_alwon_ck"), |
| 284 | DT_CLK(NULL, "l3_ick", "l3_ick"), |
| 285 | DT_CLK(NULL, "l4_ick", "l4_ick"), |
| 286 | DT_CLK(NULL, "rm_ick", "rm_ick"), |
| 287 | DT_CLK(NULL, "gpt10_fck", "gpt10_fck"), |
| 288 | DT_CLK(NULL, "gpt11_fck", "gpt11_fck"), |
| 289 | DT_CLK(NULL, "core_96m_fck", "core_96m_fck"), |
| 290 | DT_CLK(NULL, "mmchs2_fck", "mmchs2_fck"), |
| 291 | DT_CLK(NULL, "mmchs1_fck", "mmchs1_fck"), |
| 292 | DT_CLK(NULL, "i2c3_fck", "i2c3_fck"), |
| 293 | DT_CLK(NULL, "i2c2_fck", "i2c2_fck"), |
| 294 | DT_CLK(NULL, "i2c1_fck", "i2c1_fck"), |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 295 | DT_CLK(NULL, "core_48m_fck", "core_48m_fck"), |
| 296 | DT_CLK(NULL, "mcspi4_fck", "mcspi4_fck"), |
| 297 | DT_CLK(NULL, "mcspi3_fck", "mcspi3_fck"), |
| 298 | DT_CLK(NULL, "mcspi2_fck", "mcspi2_fck"), |
| 299 | DT_CLK(NULL, "mcspi1_fck", "mcspi1_fck"), |
| 300 | DT_CLK(NULL, "uart2_fck", "uart2_fck"), |
| 301 | DT_CLK(NULL, "uart1_fck", "uart1_fck"), |
| 302 | DT_CLK(NULL, "core_12m_fck", "core_12m_fck"), |
| 303 | DT_CLK("omap_hdq.0", "fck", "hdq_fck"), |
| 304 | DT_CLK(NULL, "hdq_fck", "hdq_fck"), |
| 305 | DT_CLK(NULL, "core_l3_ick", "core_l3_ick"), |
| 306 | DT_CLK(NULL, "sdrc_ick", "sdrc_ick"), |
| 307 | DT_CLK(NULL, "gpmc_fck", "gpmc_fck"), |
| 308 | DT_CLK(NULL, "core_l4_ick", "core_l4_ick"), |
| 309 | DT_CLK("omap_hsmmc.1", "ick", "mmchs2_ick"), |
| 310 | DT_CLK("omap_hsmmc.0", "ick", "mmchs1_ick"), |
| 311 | DT_CLK(NULL, "mmchs2_ick", "mmchs2_ick"), |
| 312 | DT_CLK(NULL, "mmchs1_ick", "mmchs1_ick"), |
| 313 | DT_CLK("omap_hdq.0", "ick", "hdq_ick"), |
| 314 | DT_CLK(NULL, "hdq_ick", "hdq_ick"), |
| 315 | DT_CLK("omap2_mcspi.4", "ick", "mcspi4_ick"), |
| 316 | DT_CLK("omap2_mcspi.3", "ick", "mcspi3_ick"), |
| 317 | DT_CLK("omap2_mcspi.2", "ick", "mcspi2_ick"), |
| 318 | DT_CLK("omap2_mcspi.1", "ick", "mcspi1_ick"), |
| 319 | DT_CLK(NULL, "mcspi4_ick", "mcspi4_ick"), |
| 320 | DT_CLK(NULL, "mcspi3_ick", "mcspi3_ick"), |
| 321 | DT_CLK(NULL, "mcspi2_ick", "mcspi2_ick"), |
| 322 | DT_CLK(NULL, "mcspi1_ick", "mcspi1_ick"), |
| 323 | DT_CLK("omap_i2c.3", "ick", "i2c3_ick"), |
| 324 | DT_CLK("omap_i2c.2", "ick", "i2c2_ick"), |
| 325 | DT_CLK("omap_i2c.1", "ick", "i2c1_ick"), |
| 326 | DT_CLK(NULL, "i2c3_ick", "i2c3_ick"), |
| 327 | DT_CLK(NULL, "i2c2_ick", "i2c2_ick"), |
| 328 | DT_CLK(NULL, "i2c1_ick", "i2c1_ick"), |
| 329 | DT_CLK(NULL, "uart2_ick", "uart2_ick"), |
| 330 | DT_CLK(NULL, "uart1_ick", "uart1_ick"), |
| 331 | DT_CLK(NULL, "gpt11_ick", "gpt11_ick"), |
| 332 | DT_CLK(NULL, "gpt10_ick", "gpt10_ick"), |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 333 | DT_CLK(NULL, "omapctrl_ick", "omapctrl_ick"), |
| 334 | DT_CLK(NULL, "dss_tv_fck", "dss_tv_fck"), |
| 335 | DT_CLK(NULL, "dss_96m_fck", "dss_96m_fck"), |
| 336 | DT_CLK(NULL, "dss2_alwon_fck", "dss2_alwon_fck"), |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 337 | DT_CLK(NULL, "init_60m_fclk", "dummy_ck"), |
| 338 | DT_CLK(NULL, "gpt1_fck", "gpt1_fck"), |
| 339 | DT_CLK(NULL, "aes2_ick", "aes2_ick"), |
| 340 | DT_CLK(NULL, "wkup_32k_fck", "wkup_32k_fck"), |
| 341 | DT_CLK(NULL, "gpio1_dbck", "gpio1_dbck"), |
| 342 | DT_CLK(NULL, "sha12_ick", "sha12_ick"), |
| 343 | DT_CLK(NULL, "wdt2_fck", "wdt2_fck"), |
| 344 | DT_CLK("omap_wdt", "ick", "wdt2_ick"), |
| 345 | DT_CLK(NULL, "wdt2_ick", "wdt2_ick"), |
| 346 | DT_CLK(NULL, "wdt1_ick", "wdt1_ick"), |
| 347 | DT_CLK(NULL, "gpio1_ick", "gpio1_ick"), |
| 348 | DT_CLK(NULL, "omap_32ksync_ick", "omap_32ksync_ick"), |
| 349 | DT_CLK(NULL, "gpt12_ick", "gpt12_ick"), |
| 350 | DT_CLK(NULL, "gpt1_ick", "gpt1_ick"), |
| 351 | DT_CLK(NULL, "per_96m_fck", "per_96m_fck"), |
| 352 | DT_CLK(NULL, "per_48m_fck", "per_48m_fck"), |
| 353 | DT_CLK(NULL, "uart3_fck", "uart3_fck"), |
| 354 | DT_CLK(NULL, "gpt2_fck", "gpt2_fck"), |
| 355 | DT_CLK(NULL, "gpt3_fck", "gpt3_fck"), |
| 356 | DT_CLK(NULL, "gpt4_fck", "gpt4_fck"), |
| 357 | DT_CLK(NULL, "gpt5_fck", "gpt5_fck"), |
| 358 | DT_CLK(NULL, "gpt6_fck", "gpt6_fck"), |
| 359 | DT_CLK(NULL, "gpt7_fck", "gpt7_fck"), |
| 360 | DT_CLK(NULL, "gpt8_fck", "gpt8_fck"), |
| 361 | DT_CLK(NULL, "gpt9_fck", "gpt9_fck"), |
| 362 | DT_CLK(NULL, "per_32k_alwon_fck", "per_32k_alwon_fck"), |
| 363 | DT_CLK(NULL, "gpio6_dbck", "gpio6_dbck"), |
| 364 | DT_CLK(NULL, "gpio5_dbck", "gpio5_dbck"), |
| 365 | DT_CLK(NULL, "gpio4_dbck", "gpio4_dbck"), |
| 366 | DT_CLK(NULL, "gpio3_dbck", "gpio3_dbck"), |
| 367 | DT_CLK(NULL, "gpio2_dbck", "gpio2_dbck"), |
| 368 | DT_CLK(NULL, "wdt3_fck", "wdt3_fck"), |
| 369 | DT_CLK(NULL, "per_l4_ick", "per_l4_ick"), |
| 370 | DT_CLK(NULL, "gpio6_ick", "gpio6_ick"), |
| 371 | DT_CLK(NULL, "gpio5_ick", "gpio5_ick"), |
| 372 | DT_CLK(NULL, "gpio4_ick", "gpio4_ick"), |
| 373 | DT_CLK(NULL, "gpio3_ick", "gpio3_ick"), |
| 374 | DT_CLK(NULL, "gpio2_ick", "gpio2_ick"), |
| 375 | DT_CLK(NULL, "wdt3_ick", "wdt3_ick"), |
| 376 | DT_CLK(NULL, "uart3_ick", "uart3_ick"), |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 377 | DT_CLK(NULL, "gpt9_ick", "gpt9_ick"), |
| 378 | DT_CLK(NULL, "gpt8_ick", "gpt8_ick"), |
| 379 | DT_CLK(NULL, "gpt7_ick", "gpt7_ick"), |
| 380 | DT_CLK(NULL, "gpt6_ick", "gpt6_ick"), |
| 381 | DT_CLK(NULL, "gpt5_ick", "gpt5_ick"), |
| 382 | DT_CLK(NULL, "gpt4_ick", "gpt4_ick"), |
| 383 | DT_CLK(NULL, "gpt3_ick", "gpt3_ick"), |
| 384 | DT_CLK(NULL, "gpt2_ick", "gpt2_ick"), |
Peter Ujfalusi | f757d1b | 2015-03-16 12:40:57 +0200 | [diff] [blame] | 385 | DT_CLK(NULL, "mcbsp_clks", "mcbsp_clks"), |
| 386 | DT_CLK(NULL, "mcbsp1_ick", "mcbsp1_ick"), |
| 387 | DT_CLK(NULL, "mcbsp2_ick", "mcbsp2_ick"), |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 388 | DT_CLK(NULL, "mcbsp3_ick", "mcbsp3_ick"), |
Peter Ujfalusi | f757d1b | 2015-03-16 12:40:57 +0200 | [diff] [blame] | 389 | DT_CLK(NULL, "mcbsp4_ick", "mcbsp4_ick"), |
| 390 | DT_CLK(NULL, "mcbsp5_ick", "mcbsp5_ick"), |
| 391 | DT_CLK(NULL, "mcbsp1_fck", "mcbsp1_fck"), |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 392 | DT_CLK(NULL, "mcbsp2_fck", "mcbsp2_fck"), |
| 393 | DT_CLK(NULL, "mcbsp3_fck", "mcbsp3_fck"), |
| 394 | DT_CLK(NULL, "mcbsp4_fck", "mcbsp4_fck"), |
Peter Ujfalusi | f757d1b | 2015-03-16 12:40:57 +0200 | [diff] [blame] | 395 | DT_CLK(NULL, "mcbsp5_fck", "mcbsp5_fck"), |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 396 | DT_CLK("etb", "emu_src_ck", "emu_src_ck"), |
| 397 | DT_CLK(NULL, "emu_src_ck", "emu_src_ck"), |
| 398 | DT_CLK(NULL, "pclk_fck", "pclk_fck"), |
| 399 | DT_CLK(NULL, "pclkx2_fck", "pclkx2_fck"), |
| 400 | DT_CLK(NULL, "atclk_fck", "atclk_fck"), |
| 401 | DT_CLK(NULL, "traceclk_src_fck", "traceclk_src_fck"), |
| 402 | DT_CLK(NULL, "traceclk_fck", "traceclk_fck"), |
| 403 | DT_CLK(NULL, "secure_32k_fck", "secure_32k_fck"), |
| 404 | DT_CLK(NULL, "gpt12_fck", "gpt12_fck"), |
| 405 | DT_CLK(NULL, "wdt1_fck", "wdt1_fck"), |
| 406 | DT_CLK(NULL, "timer_32k_ck", "omap_32k_fck"), |
| 407 | DT_CLK(NULL, "timer_sys_ck", "sys_ck"), |
| 408 | DT_CLK(NULL, "cpufreq_ck", "dpll1_ck"), |
| 409 | { .node_name = NULL }, |
| 410 | }; |
| 411 | |
| 412 | static struct ti_dt_clk omap34xx_omap36xx_clks[] = { |
| 413 | DT_CLK(NULL, "aes1_ick", "aes1_ick"), |
| 414 | DT_CLK("omap_rng", "ick", "rng_ick"), |
| 415 | DT_CLK("omap3-rom-rng", "ick", "rng_ick"), |
| 416 | DT_CLK(NULL, "sha11_ick", "sha11_ick"), |
| 417 | DT_CLK(NULL, "des1_ick", "des1_ick"), |
| 418 | DT_CLK(NULL, "cam_mclk", "cam_mclk"), |
| 419 | DT_CLK(NULL, "cam_ick", "cam_ick"), |
| 420 | DT_CLK(NULL, "csi2_96m_fck", "csi2_96m_fck"), |
| 421 | DT_CLK(NULL, "security_l3_ick", "security_l3_ick"), |
| 422 | DT_CLK(NULL, "pka_ick", "pka_ick"), |
| 423 | DT_CLK(NULL, "icr_ick", "icr_ick"), |
| 424 | DT_CLK("omap-aes", "ick", "aes2_ick"), |
| 425 | DT_CLK("omap-sham", "ick", "sha12_ick"), |
| 426 | DT_CLK(NULL, "des2_ick", "des2_ick"), |
| 427 | DT_CLK(NULL, "mspro_ick", "mspro_ick"), |
| 428 | DT_CLK(NULL, "mailboxes_ick", "mailboxes_ick"), |
| 429 | DT_CLK(NULL, "ssi_l4_ick", "ssi_l4_ick"), |
| 430 | DT_CLK(NULL, "sr1_fck", "sr1_fck"), |
| 431 | DT_CLK(NULL, "sr2_fck", "sr2_fck"), |
| 432 | DT_CLK(NULL, "sr_l4_ick", "sr_l4_ick"), |
| 433 | DT_CLK(NULL, "security_l4_ick2", "security_l4_ick2"), |
| 434 | DT_CLK(NULL, "wkup_l4_ick", "wkup_l4_ick"), |
| 435 | DT_CLK(NULL, "dpll2_fck", "dpll2_fck"), |
| 436 | DT_CLK(NULL, "iva2_ck", "iva2_ck"), |
| 437 | DT_CLK(NULL, "modem_fck", "modem_fck"), |
| 438 | DT_CLK(NULL, "sad2d_ick", "sad2d_ick"), |
| 439 | DT_CLK(NULL, "mad2d_ick", "mad2d_ick"), |
| 440 | DT_CLK(NULL, "mspro_fck", "mspro_fck"), |
| 441 | DT_CLK(NULL, "dpll2_ck", "dpll2_ck"), |
| 442 | DT_CLK(NULL, "dpll2_m2_ck", "dpll2_m2_ck"), |
| 443 | { .node_name = NULL }, |
| 444 | }; |
| 445 | |
| 446 | static struct ti_dt_clk omap36xx_omap3430es2plus_clks[] = { |
| 447 | DT_CLK(NULL, "ssi_ssr_fck", "ssi_ssr_fck_3430es2"), |
| 448 | DT_CLK(NULL, "ssi_sst_fck", "ssi_sst_fck_3430es2"), |
| 449 | DT_CLK("musb-omap2430", "ick", "hsotgusb_ick_3430es2"), |
| 450 | DT_CLK(NULL, "hsotgusb_ick", "hsotgusb_ick_3430es2"), |
| 451 | DT_CLK(NULL, "ssi_ick", "ssi_ick_3430es2"), |
| 452 | DT_CLK(NULL, "usim_fck", "usim_fck"), |
| 453 | DT_CLK(NULL, "usim_ick", "usim_ick"), |
| 454 | { .node_name = NULL }, |
| 455 | }; |
| 456 | |
| 457 | static struct ti_dt_clk omap3430es1_clks[] = { |
| 458 | DT_CLK(NULL, "gfx_l3_ck", "gfx_l3_ck"), |
| 459 | DT_CLK(NULL, "gfx_l3_fck", "gfx_l3_fck"), |
| 460 | DT_CLK(NULL, "gfx_l3_ick", "gfx_l3_ick"), |
| 461 | DT_CLK(NULL, "gfx_cg1_ck", "gfx_cg1_ck"), |
| 462 | DT_CLK(NULL, "gfx_cg2_ck", "gfx_cg2_ck"), |
| 463 | DT_CLK(NULL, "d2d_26m_fck", "d2d_26m_fck"), |
| 464 | DT_CLK(NULL, "fshostusb_fck", "fshostusb_fck"), |
| 465 | DT_CLK(NULL, "ssi_ssr_fck", "ssi_ssr_fck_3430es1"), |
| 466 | DT_CLK(NULL, "ssi_sst_fck", "ssi_sst_fck_3430es1"), |
| 467 | DT_CLK("musb-omap2430", "ick", "hsotgusb_ick_3430es1"), |
| 468 | DT_CLK(NULL, "hsotgusb_ick", "hsotgusb_ick_3430es1"), |
| 469 | DT_CLK(NULL, "fac_ick", "fac_ick"), |
| 470 | DT_CLK(NULL, "ssi_ick", "ssi_ick_3430es1"), |
| 471 | DT_CLK(NULL, "usb_l4_ick", "usb_l4_ick"), |
| 472 | DT_CLK(NULL, "dss1_alwon_fck", "dss1_alwon_fck_3430es1"), |
| 473 | DT_CLK("omapdss_dss", "ick", "dss_ick_3430es1"), |
| 474 | DT_CLK(NULL, "dss_ick", "dss_ick_3430es1"), |
| 475 | { .node_name = NULL }, |
| 476 | }; |
| 477 | |
| 478 | static struct ti_dt_clk omap36xx_am35xx_omap3430es2plus_clks[] = { |
| 479 | DT_CLK(NULL, "virt_16_8m_ck", "virt_16_8m_ck"), |
| 480 | DT_CLK(NULL, "dpll5_ck", "dpll5_ck"), |
| 481 | DT_CLK(NULL, "dpll5_m2_ck", "dpll5_m2_ck"), |
| 482 | DT_CLK(NULL, "sgx_fck", "sgx_fck"), |
| 483 | DT_CLK(NULL, "sgx_ick", "sgx_ick"), |
| 484 | DT_CLK(NULL, "cpefuse_fck", "cpefuse_fck"), |
| 485 | DT_CLK(NULL, "ts_fck", "ts_fck"), |
| 486 | DT_CLK(NULL, "usbtll_fck", "usbtll_fck"), |
| 487 | DT_CLK(NULL, "usbtll_ick", "usbtll_ick"), |
| 488 | DT_CLK("omap_hsmmc.2", "ick", "mmchs3_ick"), |
| 489 | DT_CLK(NULL, "mmchs3_ick", "mmchs3_ick"), |
| 490 | DT_CLK(NULL, "mmchs3_fck", "mmchs3_fck"), |
| 491 | DT_CLK(NULL, "dss1_alwon_fck", "dss1_alwon_fck_3430es2"), |
| 492 | DT_CLK("omapdss_dss", "ick", "dss_ick_3430es2"), |
| 493 | DT_CLK(NULL, "dss_ick", "dss_ick_3430es2"), |
| 494 | DT_CLK(NULL, "usbhost_120m_fck", "usbhost_120m_fck"), |
| 495 | DT_CLK(NULL, "usbhost_48m_fck", "usbhost_48m_fck"), |
| 496 | DT_CLK(NULL, "usbhost_ick", "usbhost_ick"), |
| 497 | { .node_name = NULL }, |
| 498 | }; |
| 499 | |
| 500 | static struct ti_dt_clk am35xx_clks[] = { |
| 501 | DT_CLK(NULL, "ipss_ick", "ipss_ick"), |
| 502 | DT_CLK(NULL, "rmii_ck", "rmii_ck"), |
| 503 | DT_CLK(NULL, "pclk_ck", "pclk_ck"), |
| 504 | DT_CLK(NULL, "emac_ick", "emac_ick"), |
| 505 | DT_CLK(NULL, "emac_fck", "emac_fck"), |
| 506 | DT_CLK("davinci_emac.0", NULL, "emac_ick"), |
| 507 | DT_CLK("davinci_mdio.0", NULL, "emac_fck"), |
| 508 | DT_CLK("vpfe-capture", "master", "vpfe_ick"), |
| 509 | DT_CLK("vpfe-capture", "slave", "vpfe_fck"), |
| 510 | DT_CLK(NULL, "hsotgusb_ick", "hsotgusb_ick_am35xx"), |
| 511 | DT_CLK(NULL, "hsotgusb_fck", "hsotgusb_fck_am35xx"), |
| 512 | DT_CLK(NULL, "hecc_ck", "hecc_ck"), |
| 513 | DT_CLK(NULL, "uart4_ick", "uart4_ick_am35xx"), |
| 514 | DT_CLK(NULL, "uart4_fck", "uart4_fck_am35xx"), |
| 515 | { .node_name = NULL }, |
| 516 | }; |
| 517 | |
| 518 | static struct ti_dt_clk omap36xx_clks[] = { |
| 519 | DT_CLK(NULL, "omap_192m_alwon_fck", "omap_192m_alwon_fck"), |
| 520 | DT_CLK(NULL, "uart4_fck", "uart4_fck"), |
Ben Dooks | 19e7968 | 2015-09-29 15:01:08 +0100 | [diff] [blame] | 521 | DT_CLK(NULL, "uart4_ick", "uart4_ick"), |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 522 | { .node_name = NULL }, |
| 523 | }; |
| 524 | |
| 525 | static const char *enable_init_clks[] = { |
| 526 | "sdrc_ick", |
| 527 | "gpmc_fck", |
| 528 | "omapctrl_ick", |
| 529 | }; |
| 530 | |
| 531 | enum { |
| 532 | OMAP3_SOC_AM35XX, |
| 533 | OMAP3_SOC_OMAP3430_ES1, |
| 534 | OMAP3_SOC_OMAP3430_ES2_PLUS, |
| 535 | OMAP3_SOC_OMAP3630, |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 536 | }; |
| 537 | |
Tero Kristo | 0565fb1 | 2015-03-03 13:27:48 +0200 | [diff] [blame] | 538 | /** |
| 539 | * omap3_clk_lock_dpll5 - locks DPLL5 |
| 540 | * |
| 541 | * Locks DPLL5 to a pre-defined frequency. This is required for proper |
| 542 | * operation of USB. |
| 543 | */ |
| 544 | void __init omap3_clk_lock_dpll5(void) |
| 545 | { |
| 546 | struct clk *dpll5_clk; |
| 547 | struct clk *dpll5_m2_clk; |
| 548 | |
| 549 | dpll5_clk = clk_get(NULL, "dpll5_ck"); |
| 550 | clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST); |
| 551 | clk_prepare_enable(dpll5_clk); |
| 552 | |
| 553 | /* Program dpll5_m2_clk divider for no division */ |
| 554 | dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck"); |
| 555 | clk_prepare_enable(dpll5_m2_clk); |
| 556 | clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST); |
| 557 | |
| 558 | clk_disable_unprepare(dpll5_m2_clk); |
| 559 | clk_disable_unprepare(dpll5_clk); |
| 560 | } |
| 561 | |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 562 | static int __init omap3xxx_dt_clk_init(int soc_type) |
| 563 | { |
| 564 | if (soc_type == OMAP3_SOC_AM35XX || soc_type == OMAP3_SOC_OMAP3630 || |
| 565 | soc_type == OMAP3_SOC_OMAP3430_ES1 || |
| 566 | soc_type == OMAP3_SOC_OMAP3430_ES2_PLUS) |
| 567 | ti_dt_clocks_register(omap3xxx_clks); |
| 568 | |
| 569 | if (soc_type == OMAP3_SOC_AM35XX) |
| 570 | ti_dt_clocks_register(am35xx_clks); |
| 571 | |
| 572 | if (soc_type == OMAP3_SOC_OMAP3630 || soc_type == OMAP3_SOC_AM35XX || |
| 573 | soc_type == OMAP3_SOC_OMAP3430_ES2_PLUS) |
| 574 | ti_dt_clocks_register(omap36xx_am35xx_omap3430es2plus_clks); |
| 575 | |
| 576 | if (soc_type == OMAP3_SOC_OMAP3430_ES1) |
| 577 | ti_dt_clocks_register(omap3430es1_clks); |
| 578 | |
| 579 | if (soc_type == OMAP3_SOC_OMAP3430_ES2_PLUS || |
| 580 | soc_type == OMAP3_SOC_OMAP3630) |
| 581 | ti_dt_clocks_register(omap36xx_omap3430es2plus_clks); |
| 582 | |
| 583 | if (soc_type == OMAP3_SOC_OMAP3430_ES1 || |
| 584 | soc_type == OMAP3_SOC_OMAP3430_ES2_PLUS || |
| 585 | soc_type == OMAP3_SOC_OMAP3630) |
| 586 | ti_dt_clocks_register(omap34xx_omap36xx_clks); |
| 587 | |
| 588 | if (soc_type == OMAP3_SOC_OMAP3630) |
| 589 | ti_dt_clocks_register(omap36xx_clks); |
| 590 | |
| 591 | omap2_clk_disable_autoidle_all(); |
| 592 | |
| 593 | omap2_clk_enable_init_clocks(enable_init_clks, |
| 594 | ARRAY_SIZE(enable_init_clks)); |
| 595 | |
| 596 | pr_info("Clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n", |
| 597 | (clk_get_rate(clk_get_sys(NULL, "osc_sys_ck")) / 1000000), |
| 598 | (clk_get_rate(clk_get_sys(NULL, "osc_sys_ck")) / 100000) % 10, |
| 599 | (clk_get_rate(clk_get_sys(NULL, "core_ck")) / 1000000), |
| 600 | (clk_get_rate(clk_get_sys(NULL, "arm_fck")) / 1000000)); |
| 601 | |
Tony Lindgren | 1a34275 | 2015-01-13 14:51:28 -0800 | [diff] [blame] | 602 | if (soc_type != OMAP3_SOC_OMAP3430_ES1) |
Tero Kristo | aafd900 | 2013-08-02 14:04:19 +0300 | [diff] [blame] | 603 | omap3_clk_lock_dpll5(); |
| 604 | |
| 605 | return 0; |
| 606 | } |
| 607 | |
| 608 | int __init omap3430_dt_clk_init(void) |
| 609 | { |
| 610 | return omap3xxx_dt_clk_init(OMAP3_SOC_OMAP3430_ES2_PLUS); |
| 611 | } |
| 612 | |
| 613 | int __init omap3630_dt_clk_init(void) |
| 614 | { |
| 615 | return omap3xxx_dt_clk_init(OMAP3_SOC_OMAP3630); |
| 616 | } |
| 617 | |
| 618 | int __init am35xx_dt_clk_init(void) |
| 619 | { |
| 620 | return omap3xxx_dt_clk_init(OMAP3_SOC_AM35XX); |
| 621 | } |