clk-flexgen.c (54eea32f7ed3037c91853924227585b65df909a8) | clk-flexgen.c (4e907ef6bd5eeb18bcc78f08bc993b94f007b79f) |
---|---|
1/* 2 * clk-flexgen.c 3 * 4 * Copyright (C) ST-Microelectronics SA 2013 5 * Author: Maxime Coquelin <maxime.coquelin@st.com> for ST-Microelectronics. 6 * License terms: GNU General Public License (GPL), version 2 */ 7 8#include <linux/clk-provider.h> --- 23 unchanged lines hidden (view full) --- 32#define to_flexgen(_hw) container_of(_hw, struct flexgen, hw) 33 34static int flexgen_enable(struct clk_hw *hw) 35{ 36 struct flexgen *flexgen = to_flexgen(hw); 37 struct clk_hw *pgate_hw = &flexgen->pgate.hw; 38 struct clk_hw *fgate_hw = &flexgen->fgate.hw; 39 | 1/* 2 * clk-flexgen.c 3 * 4 * Copyright (C) ST-Microelectronics SA 2013 5 * Author: Maxime Coquelin <maxime.coquelin@st.com> for ST-Microelectronics. 6 * License terms: GNU General Public License (GPL), version 2 */ 7 8#include <linux/clk-provider.h> --- 23 unchanged lines hidden (view full) --- 32#define to_flexgen(_hw) container_of(_hw, struct flexgen, hw) 33 34static int flexgen_enable(struct clk_hw *hw) 35{ 36 struct flexgen *flexgen = to_flexgen(hw); 37 struct clk_hw *pgate_hw = &flexgen->pgate.hw; 38 struct clk_hw *fgate_hw = &flexgen->fgate.hw; 39 |
40 pgate_hw->clk = hw->clk; 41 fgate_hw->clk = hw->clk; | 40 __clk_hw_set_clk(pgate_hw, hw); 41 __clk_hw_set_clk(fgate_hw, hw); |
42 43 clk_gate_ops.enable(pgate_hw); 44 45 clk_gate_ops.enable(fgate_hw); 46 47 pr_debug("%s: flexgen output enabled\n", __clk_get_name(hw->clk)); 48 return 0; 49} 50 51static void flexgen_disable(struct clk_hw *hw) 52{ 53 struct flexgen *flexgen = to_flexgen(hw); 54 struct clk_hw *fgate_hw = &flexgen->fgate.hw; 55 56 /* disable only the final gate */ | 42 43 clk_gate_ops.enable(pgate_hw); 44 45 clk_gate_ops.enable(fgate_hw); 46 47 pr_debug("%s: flexgen output enabled\n", __clk_get_name(hw->clk)); 48 return 0; 49} 50 51static void flexgen_disable(struct clk_hw *hw) 52{ 53 struct flexgen *flexgen = to_flexgen(hw); 54 struct clk_hw *fgate_hw = &flexgen->fgate.hw; 55 56 /* disable only the final gate */ |
57 fgate_hw->clk = hw->clk; | 57 __clk_hw_set_clk(fgate_hw, hw); |
58 59 clk_gate_ops.disable(fgate_hw); 60 61 pr_debug("%s: flexgen output disabled\n", __clk_get_name(hw->clk)); 62} 63 64static int flexgen_is_enabled(struct clk_hw *hw) 65{ 66 struct flexgen *flexgen = to_flexgen(hw); 67 struct clk_hw *fgate_hw = &flexgen->fgate.hw; 68 | 58 59 clk_gate_ops.disable(fgate_hw); 60 61 pr_debug("%s: flexgen output disabled\n", __clk_get_name(hw->clk)); 62} 63 64static int flexgen_is_enabled(struct clk_hw *hw) 65{ 66 struct flexgen *flexgen = to_flexgen(hw); 67 struct clk_hw *fgate_hw = &flexgen->fgate.hw; 68 |
69 fgate_hw->clk = hw->clk; | 69 __clk_hw_set_clk(fgate_hw, hw); |
70 71 if (!clk_gate_ops.is_enabled(fgate_hw)) 72 return 0; 73 74 return 1; 75} 76 77static u8 flexgen_get_parent(struct clk_hw *hw) 78{ 79 struct flexgen *flexgen = to_flexgen(hw); 80 struct clk_hw *mux_hw = &flexgen->mux.hw; 81 | 70 71 if (!clk_gate_ops.is_enabled(fgate_hw)) 72 return 0; 73 74 return 1; 75} 76 77static u8 flexgen_get_parent(struct clk_hw *hw) 78{ 79 struct flexgen *flexgen = to_flexgen(hw); 80 struct clk_hw *mux_hw = &flexgen->mux.hw; 81 |
82 mux_hw->clk = hw->clk; | 82 __clk_hw_set_clk(mux_hw, hw); |
83 84 return clk_mux_ops.get_parent(mux_hw); 85} 86 87static int flexgen_set_parent(struct clk_hw *hw, u8 index) 88{ 89 struct flexgen *flexgen = to_flexgen(hw); 90 struct clk_hw *mux_hw = &flexgen->mux.hw; 91 | 83 84 return clk_mux_ops.get_parent(mux_hw); 85} 86 87static int flexgen_set_parent(struct clk_hw *hw, u8 index) 88{ 89 struct flexgen *flexgen = to_flexgen(hw); 90 struct clk_hw *mux_hw = &flexgen->mux.hw; 91 |
92 mux_hw->clk = hw->clk; | 92 __clk_hw_set_clk(mux_hw, hw); |
93 94 return clk_mux_ops.set_parent(mux_hw, index); 95} 96 97static inline unsigned long 98clk_best_div(unsigned long parent_rate, unsigned long rate) 99{ 100 return parent_rate / rate + ((rate > (2*(parent_rate % rate))) ? 0 : 1); --- 18 unchanged lines hidden (view full) --- 119unsigned long flexgen_recalc_rate(struct clk_hw *hw, 120 unsigned long parent_rate) 121{ 122 struct flexgen *flexgen = to_flexgen(hw); 123 struct clk_hw *pdiv_hw = &flexgen->pdiv.hw; 124 struct clk_hw *fdiv_hw = &flexgen->fdiv.hw; 125 unsigned long mid_rate; 126 | 93 94 return clk_mux_ops.set_parent(mux_hw, index); 95} 96 97static inline unsigned long 98clk_best_div(unsigned long parent_rate, unsigned long rate) 99{ 100 return parent_rate / rate + ((rate > (2*(parent_rate % rate))) ? 0 : 1); --- 18 unchanged lines hidden (view full) --- 119unsigned long flexgen_recalc_rate(struct clk_hw *hw, 120 unsigned long parent_rate) 121{ 122 struct flexgen *flexgen = to_flexgen(hw); 123 struct clk_hw *pdiv_hw = &flexgen->pdiv.hw; 124 struct clk_hw *fdiv_hw = &flexgen->fdiv.hw; 125 unsigned long mid_rate; 126 |
127 pdiv_hw->clk = hw->clk; 128 fdiv_hw->clk = hw->clk; | 127 __clk_hw_set_clk(pdiv_hw, hw); 128 __clk_hw_set_clk(fdiv_hw, hw); |
129 130 mid_rate = clk_divider_ops.recalc_rate(pdiv_hw, parent_rate); 131 132 return clk_divider_ops.recalc_rate(fdiv_hw, mid_rate); 133} 134 135static int flexgen_set_rate(struct clk_hw *hw, unsigned long rate, 136 unsigned long parent_rate) 137{ 138 struct flexgen *flexgen = to_flexgen(hw); 139 struct clk_hw *pdiv_hw = &flexgen->pdiv.hw; 140 struct clk_hw *fdiv_hw = &flexgen->fdiv.hw; 141 unsigned long div = 0; 142 int ret = 0; 143 | 129 130 mid_rate = clk_divider_ops.recalc_rate(pdiv_hw, parent_rate); 131 132 return clk_divider_ops.recalc_rate(fdiv_hw, mid_rate); 133} 134 135static int flexgen_set_rate(struct clk_hw *hw, unsigned long rate, 136 unsigned long parent_rate) 137{ 138 struct flexgen *flexgen = to_flexgen(hw); 139 struct clk_hw *pdiv_hw = &flexgen->pdiv.hw; 140 struct clk_hw *fdiv_hw = &flexgen->fdiv.hw; 141 unsigned long div = 0; 142 int ret = 0; 143 |
144 pdiv_hw->clk = hw->clk; 145 fdiv_hw->clk = hw->clk; | 144 __clk_hw_set_clk(pdiv_hw, hw); 145 __clk_hw_set_clk(fdiv_hw, hw); |
146 147 div = clk_best_div(parent_rate, rate); 148 149 /* 150 * pdiv is mainly targeted for low freq results, while fdiv 151 * should be used for div <= 64. The other way round can 152 * lead to 'duty cycle' issues. 153 */ --- 189 unchanged lines hidden --- | 146 147 div = clk_best_div(parent_rate, rate); 148 149 /* 150 * pdiv is mainly targeted for low freq results, while fdiv 151 * should be used for div <= 64. The other way round can 152 * lead to 'duty cycle' issues. 153 */ --- 189 unchanged lines hidden --- |