/* * OMAP4 Clock data * * Copyright (C) 2009-2012 Texas Instruments, Inc. * Copyright (C) 2009-2010 Nokia Corporation * * Paul Walmsley (paul@pwsan.com) * Rajendra Nayak (rnayak@ti.com) * Benoit Cousson (b-cousson@ti.com) * Mike Turquette (mturquette@ti.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * XXX Some of the ES1 clocks have been removed/changed; once support * is added for discriminating clocks by ES level, these should be added back * in. */ #include #include #include #include #include #include "soc.h" #include "iomap.h" #include "clock.h" #include "clock44xx.h" #include "cm1_44xx.h" #include "cm2_44xx.h" #include "cm-regbits-44xx.h" #include "prm44xx.h" #include "prm-regbits-44xx.h" #include "control.h" #include "scrm44xx.h" /* OMAP4 modulemode control */ #define OMAP4430_MODULEMODE_HWCTRL_SHIFT 0 #define OMAP4430_MODULEMODE_SWCTRL_SHIFT 1 /* * OMAP4 ABE DPLL default frequency. In OMAP4460 TRM version V, section * "3.6.3.2.3 CM1_ABE Clock Generator" states that the "DPLL_ABE_X2_CLK * must be set to 196.608 MHz" and hence, the DPLL locked frequency is * half of this value. */ #define OMAP4_DPLL_ABE_DEFFREQ 98304000 /* Root clocks */ DEFINE_CLK_FIXED_RATE(extalt_clkin_ck, CLK_IS_ROOT, 59000000, 0x0); DEFINE_CLK_FIXED_RATE(pad_clks_src_ck, CLK_IS_ROOT, 12000000, 0x0); DEFINE_CLK_GATE(pad_clks_ck, "pad_clks_src_ck", &pad_clks_src_ck, 0x0, OMAP4430_CM_CLKSEL_ABE, OMAP4430_PAD_CLKS_GATE_SHIFT, 0x0, NULL); DEFINE_CLK_FIXED_RATE(pad_slimbus_core_clks_ck, CLK_IS_ROOT, 12000000, 0x0); DEFINE_CLK_FIXED_RATE(secure_32k_clk_src_ck, CLK_IS_ROOT, 32768, 0x0); DEFINE_CLK_FIXED_RATE(slimbus_src_clk, CLK_IS_ROOT, 12000000, 0x0); DEFINE_CLK_GATE(slimbus_clk, "slimbus_src_clk", &slimbus_src_clk, 0x0, OMAP4430_CM_CLKSEL_ABE, OMAP4430_SLIMBUS_CLK_GATE_SHIFT, 0x0, NULL); DEFINE_CLK_FIXED_RATE(sys_32k_ck, CLK_IS_ROOT, 32768, 0x0); DEFINE_CLK_FIXED_RATE(virt_12000000_ck, CLK_IS_ROOT, 12000000, 0x0); DEFINE_CLK_FIXED_RATE(virt_13000000_ck, CLK_IS_ROOT, 13000000, 0x0); DEFINE_CLK_FIXED_RATE(virt_16800000_ck, CLK_IS_ROOT, 16800000, 0x0); DEFINE_CLK_FIXED_RATE(virt_19200000_ck, CLK_IS_ROOT, 19200000, 0x0); DEFINE_CLK_FIXED_RATE(virt_26000000_ck, CLK_IS_ROOT, 26000000, 0x0); DEFINE_CLK_FIXED_RATE(virt_27000000_ck, CLK_IS_ROOT, 27000000, 0x0); DEFINE_CLK_FIXED_RATE(virt_38400000_ck, CLK_IS_ROOT, 38400000, 0x0); static const char *sys_clkin_ck_parents[] = { "virt_12000000_ck", "virt_13000000_ck", "virt_16800000_ck", "virt_19200000_ck", "virt_26000000_ck", "virt_27000000_ck", "virt_38400000_ck", }; DEFINE_CLK_MUX(sys_clkin_ck, sys_clkin_ck_parents, NULL, 0x0, OMAP4430_CM_SYS_CLKSEL, OMAP4430_SYS_CLKSEL_SHIFT, OMAP4430_SYS_CLKSEL_WIDTH, CLK_MUX_INDEX_ONE, NULL); DEFINE_CLK_FIXED_RATE(tie_low_clock_ck, CLK_IS_ROOT, 0, 0x0); DEFINE_CLK_FIXED_RATE(utmi_phy_clkout_ck, CLK_IS_ROOT, 60000000, 0x0); DEFINE_CLK_FIXED_RATE(xclk60mhsp1_ck, CLK_IS_ROOT, 60000000, 0x0); DEFINE_CLK_FIXED_RATE(xclk60mhsp2_ck, CLK_IS_ROOT, 60000000, 0x0); DEFINE_CLK_FIXED_RATE(xclk60motg_ck, CLK_IS_ROOT, 60000000, 0x0); /* Module clocks and DPLL outputs */ static const char *abe_dpll_bypass_clk_mux_ck_parents[] = { "sys_clkin_ck", "sys_32k_ck", }; DEFINE_CLK_MUX(abe_dpll_bypass_clk_mux_ck, abe_dpll_bypass_clk_mux_ck_parents, NULL, 0x0, OMAP4430_CM_L4_WKUP_CLKSEL, OMAP4430_CLKSEL_SHIFT, OMAP4430_CLKSEL_WIDTH, 0x0, NULL); DEFINE_CLK_MUX(abe_dpll_refclk_mux_ck, abe_dpll_bypass_clk_mux_ck_parents, NULL, 0x0, OMAP4430_CM_ABE_PLL_REF_CLKSEL, OMAP4430_CLKSEL_0_0_SHIFT, OMAP4430_CLKSEL_0_0_WIDTH, 0x0, NULL); /* DPLL_ABE */ static struct dpll_data dpll_abe_dd = { .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_ABE, .clk_bypass = &abe_dpll_bypass_clk_mux_ck, .clk_ref = &abe_dpll_refclk_mux_ck, .control_reg = OMAP4430_CM_CLKMODE_DPLL_ABE, .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_ABE, .idlest_reg = OMAP4430_CM_IDLEST_DPLL_ABE, .mult_mask = OMAP4430_DPLL_MULT_MASK, .div1_mask = OMAP4430_DPLL_DIV_MASK, .enable_mask = OMAP4430_DPLL_EN_MASK, .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK, .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK, .m4xen_mask = OMAP4430_DPLL_REGM4XEN_MASK, .lpmode_mask = OMAP4430_DPLL_LPMODE_EN_MASK, .max_multiplier = 2047, .max_divider = 128, .min_divider = 1, }; static const char *dpll_abe_ck_parents[] = { "abe_dpll_refclk_mux_ck", }; static struct clk dpll_abe_ck; static const struct clk_ops dpll_abe_ck_ops = { .enable = &omap3_noncore_dpll_enable, .disable = &omap3_noncore_dpll_disable, .recalc_rate = &omap4_dpll_regm4xen_recalc, .round_rate = &omap4_dpll_regm4xen_round_rate, .set_rate = &omap3_noncore_dpll_set_rate, .get_parent = &omap2_init_dpll_parent, }; static struct clk_hw_omap dpll_abe_ck_hw = { .hw = { .clk = &dpll_abe_ck, }, .dpll_data = &dpll_abe_dd, .ops = &clkhwops_omap3_dpll, }; DEFINE_STRUCT_CLK(dpll_abe_ck, dpll_abe_ck_parents, dpll_abe_ck_ops); static const char *dpll_abe_x2_ck_parents[] = { "dpll_abe_ck", }; static struct clk dpll_abe_x2_ck; static const struct clk_ops dpll_abe_x2_ck_ops = { .recalc_rate = &omap3_clkoutx2_recalc, }; static struct clk_hw_omap dpll_abe_x2_ck_hw = { .hw = { .clk = &dpll_abe_x2_ck, }, .flags = CLOCK_CLKOUTX2, .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_ABE, .ops = &clkhwops_omap4_dpllmx, }; DEFINE_STRUCT_CLK(dpll_abe_x2_ck, dpll_abe_x2_ck_parents, dpll_abe_x2_ck_ops); static const struct clk_ops omap_hsdivider_ops = { .set_rate = &omap2_clksel_set_rate, .recalc_rate = &omap2_clksel_recalc, .round_rate = &omap2_clksel_round_rate, }; DEFINE_CLK_OMAP_HSDIVIDER(dpll_abe_m2x2_ck, "dpll_abe_x2_ck", &dpll_abe_x2_ck, 0x0, OMAP4430_CM_DIV_M2_DPLL_ABE, OMAP4430_DPLL_CLKOUT_DIV_MASK); DEFINE_CLK_FIXED_FACTOR(abe_24m_fclk, "dpll_abe_m2x2_ck", &dpll_abe_m2x2_ck, 0x0, 1, 8); DEFINE_CLK_DIVIDER(abe_clk, "dpll_abe_m2x2_ck", &dpll_abe_m2x2_ck, 0x0, OMAP4430_CM_CLKSEL_ABE, OMAP4430_CLKSEL_OPP_SHIFT, OMAP4430_CLKSEL_OPP_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL); DEFINE_CLK_DIVIDER(aess_fclk, "abe_clk", &abe_clk, 0x0, OMAP4430_CM1_ABE_AESS_CLKCTRL, OMAP4430_CLKSEL_AESS_FCLK_SHIFT, OMAP4430_CLKSEL_AESS_FCLK_WIDTH, 0x0, NULL); DEFINE_CLK_OMAP_HSDIVIDER(dpll_abe_m3x2_ck, "dpll_abe_x2_ck", &dpll_abe_x2_ck, 0x0, OMAP4430_CM_DIV_M3_DPLL_ABE, OMAP4430_DPLL_CLKOUTHIF_DIV_MASK); static const char *core_hsd_byp_clk_mux_ck_parents[] = { "sys_clkin_ck", "dpll_abe_m3x2_ck", }; DEFINE_CLK_MUX(core_hsd_byp_clk_mux_ck, core_hsd_byp_clk_mux_ck_parents, NULL, 0x0, OMAP4430_CM_CLKSEL_DPLL_CORE, OMAP4430_DPLL_BYP_CLKSEL_SHIFT, OMAP4430_DPLL_BYP_CLKSEL_WIDTH, 0x0, NULL); /* DPLL_CORE */ static struct dpll_data dpll_core_dd = { .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_CORE, .clk_bypass = &core_hsd_byp_clk_mux_ck, .clk_ref = &sys_clkin_ck, .control_reg = OMAP4430_CM_CLKMODE_DPLL_CORE, .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_CORE, .idlest_reg = OMAP4430_CM_IDLEST_DPLL_CORE, .mult_mask = OMAP4430_DPLL_MULT_MASK, .div1_mask = OMAP4430_DPLL_DIV_MASK, .enable_mask = OMAP4430_DPLL_EN_MASK, .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK, .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK, .max_multiplier = 2047, .max_divider = 128, .min_divider = 1, }; static const char *dpll_core_ck_parents[] = { "sys_clkin_ck", "core_hsd_byp_clk_mux_ck" }; static struct clk dpll_core_ck; static const struct clk_ops dpll_core_ck_ops = { .recalc_rate = &omap3_dpll_recalc, .get_parent = &omap2_init_dpll_parent, }; static struct clk_hw_omap dpll_core_ck_hw = { .hw = { .clk = &dpll_core_ck, }, .dpll_data = &dpll_core_dd, .ops = &clkhwops_omap3_dpll, }; DEFINE_STRUCT_CLK(dpll_core_ck, dpll_core_ck_parents, dpll_core_ck_ops); static const char *dpll_core_x2_ck_parents[] = {