1543d9378SPaul Walmsley /* 2543d9378SPaul Walmsley * linux/arch/arm/mach-omap2/clock.h 3543d9378SPaul Walmsley * 4d8a94458SPaul Walmsley * Copyright (C) 2005-2009 Texas Instruments, Inc. 5530e544fSPaul Walmsley * Copyright (C) 2004-2011 Nokia Corporation 6a16e9703STony Lindgren * 7a16e9703STony Lindgren * Contacts: 8543d9378SPaul Walmsley * Richard Woodruff <r-woodruff2@ti.com> 9543d9378SPaul Walmsley * Paul Walmsley 10543d9378SPaul Walmsley * 11543d9378SPaul Walmsley * This program is free software; you can redistribute it and/or modify 12543d9378SPaul Walmsley * it under the terms of the GNU General Public License version 2 as 13543d9378SPaul Walmsley * published by the Free Software Foundation. 14543d9378SPaul Walmsley */ 15543d9378SPaul Walmsley 16543d9378SPaul Walmsley #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H 17543d9378SPaul Walmsley #define __ARCH_ARM_MACH_OMAP2_CLOCK_H 18543d9378SPaul Walmsley 1912706c54SPaul Walmsley #include <linux/kernel.h> 20a135eaaeSPaul Walmsley #include <linux/list.h> 2112706c54SPaul Walmsley 22e10dd62fSPaul Walmsley #include <linux/clkdev.h> 23f9ae32a7SMike Turquette #include <linux/clk-provider.h> 24f38b0dd6STero Kristo #include <linux/clk/ti.h> 25e10dd62fSPaul Walmsley 26e10dd62fSPaul Walmsley struct omap_clk { 27e10dd62fSPaul Walmsley u16 cpu; 28e10dd62fSPaul Walmsley struct clk_lookup lk; 29e10dd62fSPaul Walmsley }; 30e10dd62fSPaul Walmsley 3178e52e02SJ Keerthy #define CLK(dev, con, ck) \ 32e10dd62fSPaul Walmsley { \ 33e10dd62fSPaul Walmsley .lk = { \ 34e10dd62fSPaul Walmsley .dev_id = dev, \ 35e10dd62fSPaul Walmsley .con_id = con, \ 36e10dd62fSPaul Walmsley .clk = ck, \ 37e10dd62fSPaul Walmsley }, \ 38e10dd62fSPaul Walmsley } 39e10dd62fSPaul Walmsley 40b5a2366cSRajendra Nayak struct clockdomain; 41b5a2366cSRajendra Nayak 428c725dcdSPaul Walmsley #define DEFINE_STRUCT_CLK(_name, _parent_array_name, _clkops_name) \ 43035a61c3STomeu Vizoso static struct clk_core _name##_core = { \ 448c725dcdSPaul Walmsley .name = #_name, \ 458c725dcdSPaul Walmsley .hw = &_name##_hw.hw, \ 468c725dcdSPaul Walmsley .parent_names = _parent_array_name, \ 478c725dcdSPaul Walmsley .num_parents = ARRAY_SIZE(_parent_array_name), \ 488c725dcdSPaul Walmsley .ops = &_clkops_name, \ 49035a61c3STomeu Vizoso }; \ 50035a61c3STomeu Vizoso static struct clk _name = { \ 51035a61c3STomeu Vizoso .core = &_name##_core, \ 528c725dcdSPaul Walmsley }; 538c725dcdSPaul Walmsley 54601155b0SAfzal Mohammed #define DEFINE_STRUCT_CLK_FLAGS(_name, _parent_array_name, \ 55601155b0SAfzal Mohammed _clkops_name, _flags) \ 56035a61c3STomeu Vizoso static struct clk_core _name##_core = { \ 57601155b0SAfzal Mohammed .name = #_name, \ 58601155b0SAfzal Mohammed .hw = &_name##_hw.hw, \ 59601155b0SAfzal Mohammed .parent_names = _parent_array_name, \ 60601155b0SAfzal Mohammed .num_parents = ARRAY_SIZE(_parent_array_name), \ 61601155b0SAfzal Mohammed .ops = &_clkops_name, \ 62601155b0SAfzal Mohammed .flags = _flags, \ 63035a61c3STomeu Vizoso }; \ 64035a61c3STomeu Vizoso static struct clk _name = { \ 65035a61c3STomeu Vizoso .core = &_name##_core, \ 66601155b0SAfzal Mohammed }; 67601155b0SAfzal Mohammed 688c725dcdSPaul Walmsley #define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name) \ 698c725dcdSPaul Walmsley static struct clk_hw_omap _name##_hw = { \ 708c725dcdSPaul Walmsley .hw = { \ 718c725dcdSPaul Walmsley .clk = &_name, \ 728c725dcdSPaul Walmsley }, \ 738c725dcdSPaul Walmsley .clkdm_name = _clkdm_name, \ 748c725dcdSPaul Walmsley }; 758c725dcdSPaul Walmsley 768c725dcdSPaul Walmsley #define DEFINE_CLK_OMAP_MUX(_name, _clkdm_name, _clksel, \ 778c725dcdSPaul Walmsley _clksel_reg, _clksel_mask, \ 788c725dcdSPaul Walmsley _parent_names, _ops) \ 798c725dcdSPaul Walmsley static struct clk _name; \ 808c725dcdSPaul Walmsley static struct clk_hw_omap _name##_hw = { \ 818c725dcdSPaul Walmsley .hw = { \ 828c725dcdSPaul Walmsley .clk = &_name, \ 838c725dcdSPaul Walmsley }, \ 848c725dcdSPaul Walmsley .clksel = _clksel, \ 858c725dcdSPaul Walmsley .clksel_reg = _clksel_reg, \ 868c725dcdSPaul Walmsley .clksel_mask = _clksel_mask, \ 878c725dcdSPaul Walmsley .clkdm_name = _clkdm_name, \ 888c725dcdSPaul Walmsley }; \ 898c725dcdSPaul Walmsley DEFINE_STRUCT_CLK(_name, _parent_names, _ops); 908c725dcdSPaul Walmsley 918c725dcdSPaul Walmsley #define DEFINE_CLK_OMAP_MUX_GATE(_name, _clkdm_name, _clksel, \ 928c725dcdSPaul Walmsley _clksel_reg, _clksel_mask, \ 938c725dcdSPaul Walmsley _enable_reg, _enable_bit, \ 948c725dcdSPaul Walmsley _hwops, _parent_names, _ops) \ 958c725dcdSPaul Walmsley static struct clk _name; \ 968c725dcdSPaul Walmsley static struct clk_hw_omap _name##_hw = { \ 978c725dcdSPaul Walmsley .hw = { \ 988c725dcdSPaul Walmsley .clk = &_name, \ 998c725dcdSPaul Walmsley }, \ 1008c725dcdSPaul Walmsley .ops = _hwops, \ 1018c725dcdSPaul Walmsley .enable_reg = _enable_reg, \ 1028c725dcdSPaul Walmsley .enable_bit = _enable_bit, \ 1038c725dcdSPaul Walmsley .clksel = _clksel, \ 1048c725dcdSPaul Walmsley .clksel_reg = _clksel_reg, \ 1058c725dcdSPaul Walmsley .clksel_mask = _clksel_mask, \ 1068c725dcdSPaul Walmsley .clkdm_name = _clkdm_name, \ 1078c725dcdSPaul Walmsley }; \ 1088c725dcdSPaul Walmsley DEFINE_STRUCT_CLK(_name, _parent_names, _ops); 1098c725dcdSPaul Walmsley 110a135eaaeSPaul Walmsley /* struct clksel_rate.flags possibilities */ 111a135eaaeSPaul Walmsley #define RATE_IN_242X (1 << 0) 112a135eaaeSPaul Walmsley #define RATE_IN_243X (1 << 1) 113a135eaaeSPaul Walmsley #define RATE_IN_3430ES1 (1 << 2) /* 3430ES1 rates only */ 114a135eaaeSPaul Walmsley #define RATE_IN_3430ES2PLUS (1 << 3) /* 3430 ES >= 2 rates only */ 115a135eaaeSPaul Walmsley #define RATE_IN_36XX (1 << 4) 116a135eaaeSPaul Walmsley #define RATE_IN_4430 (1 << 5) 117a135eaaeSPaul Walmsley #define RATE_IN_TI816X (1 << 6) 118a135eaaeSPaul Walmsley #define RATE_IN_4460 (1 << 7) 119a135eaaeSPaul Walmsley #define RATE_IN_AM33XX (1 << 8) 120a135eaaeSPaul Walmsley #define RATE_IN_TI814X (1 << 9) 121a135eaaeSPaul Walmsley 122a135eaaeSPaul Walmsley #define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) 123a135eaaeSPaul Walmsley #define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS) 124a135eaaeSPaul Walmsley #define RATE_IN_3XXX (RATE_IN_34XX | RATE_IN_36XX) 125a135eaaeSPaul Walmsley #define RATE_IN_44XX (RATE_IN_4430 | RATE_IN_4460) 126a135eaaeSPaul Walmsley 127a135eaaeSPaul Walmsley /* RATE_IN_3430ES2PLUS_36XX includes 34xx/35xx with ES >=2, and all 36xx/37xx */ 128a135eaaeSPaul Walmsley #define RATE_IN_3430ES2PLUS_36XX (RATE_IN_3430ES2PLUS | RATE_IN_36XX) 129a135eaaeSPaul Walmsley 130a135eaaeSPaul Walmsley 131a135eaaeSPaul Walmsley /** 132a135eaaeSPaul Walmsley * struct clksel_rate - register bitfield values corresponding to clk divisors 133a135eaaeSPaul Walmsley * @val: register bitfield value (shifted to bit 0) 134a135eaaeSPaul Walmsley * @div: clock divisor corresponding to @val 135a135eaaeSPaul Walmsley * @flags: (see "struct clksel_rate.flags possibilities" above) 136a135eaaeSPaul Walmsley * 137a135eaaeSPaul Walmsley * @val should match the value of a read from struct clk.clksel_reg 138a135eaaeSPaul Walmsley * AND'ed with struct clk.clksel_mask, shifted right to bit 0. 139a135eaaeSPaul Walmsley * 140a135eaaeSPaul Walmsley * @div is the divisor that should be applied to the parent clock's rate 141a135eaaeSPaul Walmsley * to produce the current clock's rate. 142a135eaaeSPaul Walmsley */ 143a135eaaeSPaul Walmsley struct clksel_rate { 144a135eaaeSPaul Walmsley u32 val; 145a135eaaeSPaul Walmsley u8 div; 146a135eaaeSPaul Walmsley u16 flags; 147a135eaaeSPaul Walmsley }; 148a135eaaeSPaul Walmsley 149a135eaaeSPaul Walmsley /** 150a135eaaeSPaul Walmsley * struct clksel - available parent clocks, and a pointer to their divisors 151a135eaaeSPaul Walmsley * @parent: struct clk * to a possible parent clock 152a135eaaeSPaul Walmsley * @rates: available divisors for this parent clock 153a135eaaeSPaul Walmsley * 154a135eaaeSPaul Walmsley * A struct clksel is always associated with one or more struct clks 155a135eaaeSPaul Walmsley * and one or more struct clksel_rates. 156a135eaaeSPaul Walmsley */ 157a135eaaeSPaul Walmsley struct clksel { 158a135eaaeSPaul Walmsley struct clk *parent; 159a135eaaeSPaul Walmsley const struct clksel_rate *rates; 160a135eaaeSPaul Walmsley }; 161a135eaaeSPaul Walmsley 162c0bf3132SRussell King /* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */ 163c0bf3132SRussell King #define CORE_CLK_SRC_32K 0x0 164c0bf3132SRussell King #define CORE_CLK_SRC_DPLL 0x1 165c0bf3132SRussell King #define CORE_CLK_SRC_DPLL_X2 0x2 166c0bf3132SRussell King 167c0bf3132SRussell King /* OMAP2xxx CM_CLKEN_PLL.EN_DPLL bits - for omap2_get_dpll_rate() */ 168c0bf3132SRussell King #define OMAP2XXX_EN_DPLL_LPBYPASS 0x1 169c0bf3132SRussell King #define OMAP2XXX_EN_DPLL_FRBYPASS 0x2 170c0bf3132SRussell King #define OMAP2XXX_EN_DPLL_LOCKED 0x3 171c0bf3132SRussell King 172c0bf3132SRussell King /* OMAP3xxx CM_CLKEN_PLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */ 173c0bf3132SRussell King #define OMAP3XXX_EN_DPLL_LPBYPASS 0x5 174c0bf3132SRussell King #define OMAP3XXX_EN_DPLL_FRBYPASS 0x6 175c0bf3132SRussell King #define OMAP3XXX_EN_DPLL_LOCKED 0x7 176c0bf3132SRussell King 17716975a79SRajendra Nayak /* OMAP4xxx CM_CLKMODE_DPLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */ 17816975a79SRajendra Nayak #define OMAP4XXX_EN_DPLL_MNBYPASS 0x4 17916975a79SRajendra Nayak #define OMAP4XXX_EN_DPLL_LPBYPASS 0x5 18016975a79SRajendra Nayak #define OMAP4XXX_EN_DPLL_FRBYPASS 0x6 18116975a79SRajendra Nayak #define OMAP4XXX_EN_DPLL_LOCKED 0x7 18216975a79SRajendra Nayak 18332cc0021SMike Turquette u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk); 18432cc0021SMike Turquette void omap3_dpll_allow_idle(struct clk_hw_omap *clk); 18532cc0021SMike Turquette void omap3_dpll_deny_idle(struct clk_hw_omap *clk); 18632cc0021SMike Turquette void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk); 18732cc0021SMike Turquette void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk); 188543d9378SPaul Walmsley 18912706c54SPaul Walmsley void __init omap2_clk_disable_clkdm_control(void); 190435699dbSPaul Walmsley 191435699dbSPaul Walmsley /* clkt_clksel.c public functions */ 19232cc0021SMike Turquette u32 omap2_clksel_round_rate_div(struct clk_hw_omap *clk, 19332cc0021SMike Turquette unsigned long target_rate, 19432cc0021SMike Turquette u32 *new_div); 19532cc0021SMike Turquette u8 omap2_clksel_find_parent_index(struct clk_hw *hw); 19632cc0021SMike Turquette unsigned long omap2_clksel_recalc(struct clk_hw *hw, unsigned long parent_rate); 19732cc0021SMike Turquette long omap2_clksel_round_rate(struct clk_hw *hw, unsigned long target_rate, 19832cc0021SMike Turquette unsigned long *parent_rate); 19932cc0021SMike Turquette int omap2_clksel_set_rate(struct clk_hw *hw, unsigned long rate, 20032cc0021SMike Turquette unsigned long parent_rate); 20132cc0021SMike Turquette int omap2_clksel_set_parent(struct clk_hw *hw, u8 field_val); 202435699dbSPaul Walmsley 203530e544fSPaul Walmsley /* clkt_iclk.c public functions */ 204b4777a21SRajendra Nayak extern void omap2_clkt_iclk_allow_idle(struct clk_hw_omap *clk); 205b4777a21SRajendra Nayak extern void omap2_clkt_iclk_deny_idle(struct clk_hw_omap *clk); 206530e544fSPaul Walmsley 20732cc0021SMike Turquette unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk); 208435699dbSPaul Walmsley 20932cc0021SMike Turquette void omap2_clk_dflt_find_companion(struct clk_hw_omap *clk, 21032cc0021SMike Turquette void __iomem **other_reg, 21132cc0021SMike Turquette u8 *other_bit); 21232cc0021SMike Turquette void omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, 21332cc0021SMike Turquette void __iomem **idlest_reg, 21432cc0021SMike Turquette u8 *idlest_bit, u8 *idlest_val); 21523fb8ba3SRajendra Nayak int omap2_clk_enable_autoidle_all(void); 216818b40e5STero Kristo int omap2_clk_allow_idle(struct clk *clk); 217818b40e5STero Kristo int omap2_clk_deny_idle(struct clk *clk); 2184d30e82cSPaul Walmsley int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name); 2194d30e82cSPaul Walmsley void omap2_clk_print_new_rates(const char *hfclkin_ck_name, 2204d30e82cSPaul Walmsley const char *core_ck_name, 2214d30e82cSPaul Walmsley const char *mpu_ck_name); 222543d9378SPaul Walmsley 2233ada6b10STero Kristo u32 omap2_clk_readl(struct clk_hw_omap *clk, void __iomem *reg); 2243ada6b10STero Kristo void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg); 2253ada6b10STero Kristo 22699541195SAfzal Mohammed extern u16 cpu_mask; 227d8a94458SPaul Walmsley 2288111e010STero Kristo /* 2298111e010STero Kristo * Clock features setup. Used instead of CPU type checks. 2308111e010STero Kristo */ 2318111e010STero Kristo struct ti_clk_features { 2328111e010STero Kristo u32 flags; 233a24886e2STero Kristo long fint_min; 234a24886e2STero Kristo long fint_max; 235a24886e2STero Kristo long fint_band1_max; 236a24886e2STero Kristo long fint_band2_min; 237512d91cbSTero Kristo u8 dpll_bypass_vals; 238066edb2dSTero Kristo u8 cm_idlest_val; 2398111e010STero Kristo }; 2402337c5b5STero Kristo 2412337c5b5STero Kristo #define TI_CLK_DPLL_HAS_FREQSEL (1 << 0) 242f0d2f68aSTero Kristo #define TI_CLK_DPLL4_DENY_REPROGRAM (1 << 1) 2432337c5b5STero Kristo 2448111e010STero Kristo extern struct ti_clk_features ti_clk_features; 2458111e010STero Kristo 246b36ee724SRussell King extern const struct clkops clkops_omap2_dflt_wait; 247bc51da4eSRussell King extern const struct clkops clkops_omap2_dflt; 248b36ee724SRussell King 24982e9bd58SPaul Walmsley extern struct clk_functions omap2_clk_functions; 25082e9bd58SPaul Walmsley 251d8a94458SPaul Walmsley extern const struct clksel_rate gpt_32k_rates[]; 252d8a94458SPaul Walmsley extern const struct clksel_rate gpt_sys_rates[]; 253d8a94458SPaul Walmsley extern const struct clksel_rate gfx_l3_rates[]; 25422411396SPaul Walmsley extern const struct clksel_rate dsp_ick_rates[]; 255543d9378SPaul Walmsley 25632cc0021SMike Turquette extern const struct clk_hw_omap_ops clkhwops_iclk_wait; 25732cc0021SMike Turquette extern const struct clk_hw_omap_ops clkhwops_wait; 258b4777a21SRajendra Nayak extern const struct clk_hw_omap_ops clkhwops_omap3430es2_ssi_wait; 259b4777a21SRajendra Nayak extern const struct clk_hw_omap_ops clkhwops_omap3430es2_dss_usbhost_wait; 260b4777a21SRajendra Nayak extern const struct clk_hw_omap_ops clkhwops_omap3430es2_hsotgusb_wait; 261b4777a21SRajendra Nayak extern const struct clk_hw_omap_ops clkhwops_am35xx_ipss_module_wait; 262b4777a21SRajendra Nayak extern const struct clk_hw_omap_ops clkhwops_apll54; 263b4777a21SRajendra Nayak extern const struct clk_hw_omap_ops clkhwops_apll96; 264657ebfadSPaul Walmsley 265571efa0dSPaul Walmsley /* clksel_rate blocks shared between OMAP44xx and AM33xx */ 266571efa0dSPaul Walmsley extern const struct clksel_rate div_1_0_rates[]; 267cb26867eSRajendra Nayak extern const struct clksel_rate div3_1to4_rates[]; 268571efa0dSPaul Walmsley extern const struct clksel_rate div_1_1_rates[]; 269571efa0dSPaul Walmsley extern const struct clksel_rate div_1_2_rates[]; 270571efa0dSPaul Walmsley extern const struct clksel_rate div_1_3_rates[]; 271571efa0dSPaul Walmsley extern const struct clksel_rate div_1_4_rates[]; 272571efa0dSPaul Walmsley extern const struct clksel_rate div31_1to31_rates[]; 273571efa0dSPaul Walmsley 27432cc0021SMike Turquette extern int omap2_clkops_enable_clkdm(struct clk_hw *hw); 27532cc0021SMike Turquette extern void omap2_clkops_disable_clkdm(struct clk_hw *hw); 27632cc0021SMike Turquette 277*9f029b15STero Kristo int __init omap2_clk_provider_init(struct device_node *np, int index, 278*9f029b15STero Kristo void __iomem *mem); 279*9f029b15STero Kristo void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem); 280*9f029b15STero Kristo 2818111e010STero Kristo void __init ti_clk_init_features(void); 282543d9378SPaul Walmsley #endif 283