0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/list.h>
0011 #include <linux/clk.h>
0012 #include <linux/clk-provider.h>
0013 #include <linux/clk/ti.h>
0014
0015 #include "clock.h"
0016
0017 #define OMAP3430ES2_ST_DSS_IDLE_SHIFT 1
0018 #define OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT 5
0019 #define OMAP3430ES2_ST_SSI_IDLE_SHIFT 8
0020
0021 #define OMAP34XX_CM_IDLEST_VAL 1
0022
0023
0024
0025
0026
0027
0028 #define AM35XX_IPSS_ICK_MASK 0xF
0029 #define AM35XX_IPSS_ICK_EN_ACK_OFFSET 0x4
0030 #define AM35XX_IPSS_ICK_FCK_OFFSET 0x8
0031 #define AM35XX_IPSS_CLK_IDLEST_VAL 0
0032
0033 #define AM35XX_ST_IPSS_SHIFT 5
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 static void omap3430es2_clk_ssi_find_idlest(struct clk_hw_omap *clk,
0047 struct clk_omap_reg *idlest_reg,
0048 u8 *idlest_bit,
0049 u8 *idlest_val)
0050 {
0051 memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg));
0052 idlest_reg->offset &= ~0xf0;
0053 idlest_reg->offset |= 0x20;
0054 *idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT;
0055 *idlest_val = OMAP34XX_CM_IDLEST_VAL;
0056 }
0057
0058 const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_ssi_wait = {
0059 .allow_idle = omap2_clkt_iclk_allow_idle,
0060 .deny_idle = omap2_clkt_iclk_deny_idle,
0061 .find_idlest = omap3430es2_clk_ssi_find_idlest,
0062 .find_companion = omap2_clk_dflt_find_companion,
0063 };
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 static void
0080 omap3430es2_clk_dss_usbhost_find_idlest(struct clk_hw_omap *clk,
0081 struct clk_omap_reg *idlest_reg,
0082 u8 *idlest_bit, u8 *idlest_val)
0083 {
0084 memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg));
0085
0086 idlest_reg->offset &= ~0xf0;
0087 idlest_reg->offset |= 0x20;
0088
0089 *idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT;
0090 *idlest_val = OMAP34XX_CM_IDLEST_VAL;
0091 }
0092
0093 const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait = {
0094 .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest,
0095 .find_companion = omap2_clk_dflt_find_companion,
0096 };
0097
0098 const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_dss_usbhost_wait = {
0099 .allow_idle = omap2_clkt_iclk_allow_idle,
0100 .deny_idle = omap2_clkt_iclk_deny_idle,
0101 .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest,
0102 .find_companion = omap2_clk_dflt_find_companion,
0103 };
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116 static void
0117 omap3430es2_clk_hsotgusb_find_idlest(struct clk_hw_omap *clk,
0118 struct clk_omap_reg *idlest_reg,
0119 u8 *idlest_bit,
0120 u8 *idlest_val)
0121 {
0122 memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg));
0123 idlest_reg->offset &= ~0xf0;
0124 idlest_reg->offset |= 0x20;
0125 *idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT;
0126 *idlest_val = OMAP34XX_CM_IDLEST_VAL;
0127 }
0128
0129 const struct clk_hw_omap_ops clkhwops_omap3430es2_iclk_hsotgusb_wait = {
0130 .allow_idle = omap2_clkt_iclk_allow_idle,
0131 .deny_idle = omap2_clkt_iclk_deny_idle,
0132 .find_idlest = omap3430es2_clk_hsotgusb_find_idlest,
0133 .find_companion = omap2_clk_dflt_find_companion,
0134 };
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 static void am35xx_clk_find_idlest(struct clk_hw_omap *clk,
0148 struct clk_omap_reg *idlest_reg,
0149 u8 *idlest_bit,
0150 u8 *idlest_val)
0151 {
0152 memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg));
0153 *idlest_bit = clk->enable_bit + AM35XX_IPSS_ICK_EN_ACK_OFFSET;
0154 *idlest_val = AM35XX_IPSS_CLK_IDLEST_VAL;
0155 }
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171 static void am35xx_clk_find_companion(struct clk_hw_omap *clk,
0172 struct clk_omap_reg *other_reg,
0173 u8 *other_bit)
0174 {
0175 memcpy(other_reg, &clk->enable_reg, sizeof(*other_reg));
0176 if (clk->enable_bit & AM35XX_IPSS_ICK_MASK)
0177 *other_bit = clk->enable_bit + AM35XX_IPSS_ICK_FCK_OFFSET;
0178 else
0179 *other_bit = clk->enable_bit - AM35XX_IPSS_ICK_FCK_OFFSET;
0180 }
0181
0182 const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait = {
0183 .find_idlest = am35xx_clk_find_idlest,
0184 .find_companion = am35xx_clk_find_companion,
0185 };
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198 static void am35xx_clk_ipss_find_idlest(struct clk_hw_omap *clk,
0199 struct clk_omap_reg *idlest_reg,
0200 u8 *idlest_bit,
0201 u8 *idlest_val)
0202 {
0203 memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg));
0204
0205 idlest_reg->offset &= ~0xf0;
0206 idlest_reg->offset |= 0x20;
0207 *idlest_bit = AM35XX_ST_IPSS_SHIFT;
0208 *idlest_val = OMAP34XX_CM_IDLEST_VAL;
0209 }
0210
0211 const struct clk_hw_omap_ops clkhwops_am35xx_ipss_wait = {
0212 .allow_idle = omap2_clkt_iclk_allow_idle,
0213 .deny_idle = omap2_clkt_iclk_deny_idle,
0214 .find_idlest = am35xx_clk_ipss_find_idlest,
0215 .find_companion = omap2_clk_dflt_find_companion,
0216 };
0217
0218 static struct ti_dt_clk omap3xxx_clks[] = {
0219 DT_CLK(NULL, "timer_32k_ck", "omap_32k_fck"),
0220 DT_CLK(NULL, "timer_sys_ck", "sys_ck"),
0221 { .node_name = NULL },
0222 };
0223
0224 static struct ti_dt_clk omap36xx_omap3430es2plus_clks[] = {
0225 DT_CLK(NULL, "ssi_ssr_fck", "ssi_ssr_fck_3430es2"),
0226 DT_CLK(NULL, "ssi_sst_fck", "ssi_sst_fck_3430es2"),
0227 DT_CLK(NULL, "hsotgusb_ick", "hsotgusb_ick_3430es2"),
0228 DT_CLK(NULL, "ssi_ick", "ssi_ick_3430es2"),
0229 { .node_name = NULL },
0230 };
0231
0232 static struct ti_dt_clk omap3430es1_clks[] = {
0233 DT_CLK(NULL, "ssi_ssr_fck", "ssi_ssr_fck_3430es1"),
0234 DT_CLK(NULL, "ssi_sst_fck", "ssi_sst_fck_3430es1"),
0235 DT_CLK(NULL, "hsotgusb_ick", "hsotgusb_ick_3430es1"),
0236 DT_CLK(NULL, "ssi_ick", "ssi_ick_3430es1"),
0237 DT_CLK(NULL, "dss1_alwon_fck", "dss1_alwon_fck_3430es1"),
0238 DT_CLK(NULL, "dss_ick", "dss_ick_3430es1"),
0239 { .node_name = NULL },
0240 };
0241
0242 static struct ti_dt_clk omap36xx_am35xx_omap3430es2plus_clks[] = {
0243 DT_CLK(NULL, "dss1_alwon_fck", "dss1_alwon_fck_3430es2"),
0244 DT_CLK(NULL, "dss_ick", "dss_ick_3430es2"),
0245 { .node_name = NULL },
0246 };
0247
0248 static struct ti_dt_clk am35xx_clks[] = {
0249 DT_CLK(NULL, "hsotgusb_ick", "hsotgusb_ick_am35xx"),
0250 DT_CLK(NULL, "hsotgusb_fck", "hsotgusb_fck_am35xx"),
0251 DT_CLK(NULL, "uart4_ick", "uart4_ick_am35xx"),
0252 DT_CLK(NULL, "uart4_fck", "uart4_fck_am35xx"),
0253 { .node_name = NULL },
0254 };
0255
0256 static const char *enable_init_clks[] = {
0257 "sdrc_ick",
0258 "gpmc_fck",
0259 "omapctrl_ick",
0260 };
0261
0262 enum {
0263 OMAP3_SOC_AM35XX,
0264 OMAP3_SOC_OMAP3430_ES1,
0265 OMAP3_SOC_OMAP3430_ES2_PLUS,
0266 OMAP3_SOC_OMAP3630,
0267 };
0268
0269
0270
0271
0272
0273
0274
0275 void __init omap3_clk_lock_dpll5(void)
0276 {
0277 struct clk *dpll5_clk;
0278 struct clk *dpll5_m2_clk;
0279
0280
0281
0282
0283
0284
0285
0286
0287 dpll5_clk = clk_get(NULL, "dpll5_ck");
0288 clk_set_rate(dpll5_clk, OMAP3_DPLL5_FREQ_FOR_USBHOST * 8);
0289 clk_prepare_enable(dpll5_clk);
0290
0291
0292 dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
0293 clk_prepare_enable(dpll5_m2_clk);
0294 clk_set_rate(dpll5_m2_clk, OMAP3_DPLL5_FREQ_FOR_USBHOST);
0295
0296 clk_disable_unprepare(dpll5_m2_clk);
0297 clk_disable_unprepare(dpll5_clk);
0298 }
0299
0300 static int __init omap3xxx_dt_clk_init(int soc_type)
0301 {
0302 if (soc_type == OMAP3_SOC_AM35XX || soc_type == OMAP3_SOC_OMAP3630 ||
0303 soc_type == OMAP3_SOC_OMAP3430_ES1 ||
0304 soc_type == OMAP3_SOC_OMAP3430_ES2_PLUS)
0305 ti_dt_clocks_register(omap3xxx_clks);
0306
0307 if (soc_type == OMAP3_SOC_AM35XX)
0308 ti_dt_clocks_register(am35xx_clks);
0309
0310 if (soc_type == OMAP3_SOC_OMAP3630 || soc_type == OMAP3_SOC_AM35XX ||
0311 soc_type == OMAP3_SOC_OMAP3430_ES2_PLUS)
0312 ti_dt_clocks_register(omap36xx_am35xx_omap3430es2plus_clks);
0313
0314 if (soc_type == OMAP3_SOC_OMAP3430_ES1)
0315 ti_dt_clocks_register(omap3430es1_clks);
0316
0317 if (soc_type == OMAP3_SOC_OMAP3430_ES2_PLUS ||
0318 soc_type == OMAP3_SOC_OMAP3630)
0319 ti_dt_clocks_register(omap36xx_omap3430es2plus_clks);
0320
0321 omap2_clk_disable_autoidle_all();
0322
0323 ti_clk_add_aliases();
0324
0325 omap2_clk_enable_init_clocks(enable_init_clks,
0326 ARRAY_SIZE(enable_init_clks));
0327
0328 pr_info("Clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n",
0329 (clk_get_rate(clk_get_sys(NULL, "osc_sys_ck")) / 1000000),
0330 (clk_get_rate(clk_get_sys(NULL, "osc_sys_ck")) / 100000) % 10,
0331 (clk_get_rate(clk_get_sys(NULL, "core_ck")) / 1000000),
0332 (clk_get_rate(clk_get_sys(NULL, "arm_fck")) / 1000000));
0333
0334 if (soc_type != OMAP3_SOC_OMAP3430_ES1)
0335 omap3_clk_lock_dpll5();
0336
0337 return 0;
0338 }
0339
0340 int __init omap3430_dt_clk_init(void)
0341 {
0342 return omap3xxx_dt_clk_init(OMAP3_SOC_OMAP3430_ES2_PLUS);
0343 }
0344
0345 int __init omap3630_dt_clk_init(void)
0346 {
0347 return omap3xxx_dt_clk_init(OMAP3_SOC_OMAP3630);
0348 }
0349
0350 int __init am35xx_dt_clk_init(void)
0351 {
0352 return omap3xxx_dt_clk_init(OMAP3_SOC_AM35XX);
0353 }