Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 //
0003 // OWL composite clock driver
0004 //
0005 // Copyright (c) 2014 Actions Semi Inc.
0006 // Author: David Liu <liuwei@actions-semi.com>
0007 //
0008 // Copyright (c) 2018 Linaro Ltd.
0009 // Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
0010 
0011 #include <linux/clk-provider.h>
0012 #include <linux/regmap.h>
0013 
0014 #include "owl-composite.h"
0015 
0016 static u8 owl_comp_get_parent(struct clk_hw *hw)
0017 {
0018     struct owl_composite *comp = hw_to_owl_comp(hw);
0019 
0020     return owl_mux_helper_get_parent(&comp->common, &comp->mux_hw);
0021 }
0022 
0023 static int owl_comp_set_parent(struct clk_hw *hw, u8 index)
0024 {
0025     struct owl_composite *comp = hw_to_owl_comp(hw);
0026 
0027     return owl_mux_helper_set_parent(&comp->common, &comp->mux_hw, index);
0028 }
0029 
0030 static void owl_comp_disable(struct clk_hw *hw)
0031 {
0032     struct owl_composite *comp = hw_to_owl_comp(hw);
0033     struct owl_clk_common *common = &comp->common;
0034 
0035     owl_gate_set(common, &comp->gate_hw, false);
0036 }
0037 
0038 static int owl_comp_enable(struct clk_hw *hw)
0039 {
0040     struct owl_composite *comp = hw_to_owl_comp(hw);
0041     struct owl_clk_common *common = &comp->common;
0042 
0043     owl_gate_set(common, &comp->gate_hw, true);
0044 
0045     return 0;
0046 }
0047 
0048 static int owl_comp_is_enabled(struct clk_hw *hw)
0049 {
0050     struct owl_composite *comp = hw_to_owl_comp(hw);
0051     struct owl_clk_common *common = &comp->common;
0052 
0053     return owl_gate_clk_is_enabled(common, &comp->gate_hw);
0054 }
0055 
0056 static long owl_comp_div_round_rate(struct clk_hw *hw, unsigned long rate,
0057                 unsigned long *parent_rate)
0058 {
0059     struct owl_composite *comp = hw_to_owl_comp(hw);
0060 
0061     return owl_divider_helper_round_rate(&comp->common, &comp->rate.div_hw,
0062                     rate, parent_rate);
0063 }
0064 
0065 static unsigned long owl_comp_div_recalc_rate(struct clk_hw *hw,
0066                       unsigned long parent_rate)
0067 {
0068     struct owl_composite *comp = hw_to_owl_comp(hw);
0069 
0070     return owl_divider_helper_recalc_rate(&comp->common, &comp->rate.div_hw,
0071                     parent_rate);
0072 }
0073 
0074 static int owl_comp_div_set_rate(struct clk_hw *hw, unsigned long rate,
0075                 unsigned long parent_rate)
0076 {
0077     struct owl_composite *comp = hw_to_owl_comp(hw);
0078 
0079     return owl_divider_helper_set_rate(&comp->common, &comp->rate.div_hw,
0080                     rate, parent_rate);
0081 }
0082 
0083 static long owl_comp_fact_round_rate(struct clk_hw *hw, unsigned long rate,
0084             unsigned long *parent_rate)
0085 {
0086     struct owl_composite *comp = hw_to_owl_comp(hw);
0087 
0088     return owl_factor_helper_round_rate(&comp->common,
0089                     &comp->rate.factor_hw,
0090                     rate, parent_rate);
0091 }
0092 
0093 static unsigned long owl_comp_fact_recalc_rate(struct clk_hw *hw,
0094             unsigned long parent_rate)
0095 {
0096     struct owl_composite *comp = hw_to_owl_comp(hw);
0097 
0098     return owl_factor_helper_recalc_rate(&comp->common,
0099                     &comp->rate.factor_hw,
0100                     parent_rate);
0101 }
0102 
0103 static int owl_comp_fact_set_rate(struct clk_hw *hw, unsigned long rate,
0104             unsigned long parent_rate)
0105 {
0106     struct owl_composite *comp = hw_to_owl_comp(hw);
0107 
0108     return owl_factor_helper_set_rate(&comp->common,
0109                     &comp->rate.factor_hw,
0110                     rate, parent_rate);
0111 }
0112 
0113 static long owl_comp_fix_fact_round_rate(struct clk_hw *hw, unsigned long rate,
0114             unsigned long *parent_rate)
0115 {
0116     struct owl_composite *comp = hw_to_owl_comp(hw);
0117     struct clk_fixed_factor *fix_fact_hw = &comp->rate.fix_fact_hw;
0118 
0119     return comp->fix_fact_ops->round_rate(&fix_fact_hw->hw, rate, parent_rate);
0120 }
0121 
0122 static unsigned long owl_comp_fix_fact_recalc_rate(struct clk_hw *hw,
0123             unsigned long parent_rate)
0124 {
0125     struct owl_composite *comp = hw_to_owl_comp(hw);
0126     struct clk_fixed_factor *fix_fact_hw = &comp->rate.fix_fact_hw;
0127 
0128     return comp->fix_fact_ops->recalc_rate(&fix_fact_hw->hw, parent_rate);
0129 
0130 }
0131 
0132 static int owl_comp_fix_fact_set_rate(struct clk_hw *hw, unsigned long rate,
0133             unsigned long parent_rate)
0134 {
0135     /*
0136      * We must report success but we can do so unconditionally because
0137      * owl_comp_fix_fact_round_rate returns values that ensure this call is
0138      * a nop.
0139      */
0140 
0141     return 0;
0142 }
0143 
0144 const struct clk_ops owl_comp_div_ops = {
0145     /* mux_ops */
0146     .get_parent = owl_comp_get_parent,
0147     .set_parent = owl_comp_set_parent,
0148 
0149     /* gate_ops */
0150     .disable    = owl_comp_disable,
0151     .enable     = owl_comp_enable,
0152     .is_enabled = owl_comp_is_enabled,
0153 
0154     /* div_ops */
0155     .round_rate = owl_comp_div_round_rate,
0156     .recalc_rate    = owl_comp_div_recalc_rate,
0157     .set_rate   = owl_comp_div_set_rate,
0158 };
0159 
0160 
0161 const struct clk_ops owl_comp_fact_ops = {
0162     /* mux_ops */
0163     .get_parent = owl_comp_get_parent,
0164     .set_parent = owl_comp_set_parent,
0165 
0166     /* gate_ops */
0167     .disable    = owl_comp_disable,
0168     .enable     = owl_comp_enable,
0169     .is_enabled = owl_comp_is_enabled,
0170 
0171     /* fact_ops */
0172     .round_rate = owl_comp_fact_round_rate,
0173     .recalc_rate    = owl_comp_fact_recalc_rate,
0174     .set_rate   = owl_comp_fact_set_rate,
0175 };
0176 
0177 const struct clk_ops owl_comp_fix_fact_ops = {
0178     /* gate_ops */
0179     .disable    = owl_comp_disable,
0180     .enable     = owl_comp_enable,
0181     .is_enabled = owl_comp_is_enabled,
0182 
0183     /* fix_fact_ops */
0184     .round_rate = owl_comp_fix_fact_round_rate,
0185     .recalc_rate    = owl_comp_fix_fact_recalc_rate,
0186     .set_rate   = owl_comp_fix_fact_set_rate,
0187 };
0188 
0189 
0190 const struct clk_ops owl_comp_pass_ops = {
0191     /* mux_ops */
0192     .get_parent = owl_comp_get_parent,
0193     .set_parent = owl_comp_set_parent,
0194 
0195     /* gate_ops */
0196     .disable    = owl_comp_disable,
0197     .enable     = owl_comp_enable,
0198     .is_enabled = owl_comp_is_enabled,
0199 };