Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: qcom: clk-alpha-pll: add Rivian EVO PLL configuration interfaces

Add and export Rivian EVO PLL configuration and control functions to
clock controller drivers, the PLL is used by SM8450 camera clock
controller.

Reviewed-by: Stephen Boyd <sboyd@kernel.org>
Reviewed-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/20220701062739.2757912-1-vladimir.zapolskiy@linaro.org

authored by

Vladimir Zapolskiy and committed by
Bjorn Andersson
bbc78013 260e3660

+76
+70
drivers/clk/qcom/clk-alpha-pll.c
··· 154 154 [PLL_OFF_TEST_CTL_U] = 0x30, 155 155 [PLL_OFF_TEST_CTL_U1] = 0x34, 156 156 }, 157 + [CLK_ALPHA_PLL_TYPE_RIVIAN_EVO] = { 158 + [PLL_OFF_OPMODE] = 0x04, 159 + [PLL_OFF_STATUS] = 0x0c, 160 + [PLL_OFF_L_VAL] = 0x10, 161 + [PLL_OFF_USER_CTL] = 0x14, 162 + [PLL_OFF_USER_CTL_U] = 0x18, 163 + [PLL_OFF_CONFIG_CTL] = 0x1c, 164 + [PLL_OFF_CONFIG_CTL_U] = 0x20, 165 + [PLL_OFF_CONFIG_CTL_U1] = 0x24, 166 + [PLL_OFF_TEST_CTL] = 0x28, 167 + [PLL_OFF_TEST_CTL_U] = 0x2c, 168 + }, 157 169 }; 158 170 EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); 159 171 ··· 2190 2178 .set_rate = alpha_pll_lucid_5lpe_set_rate, 2191 2179 }; 2192 2180 EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_evo_ops); 2181 + 2182 + void clk_rivian_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 2183 + const struct alpha_pll_config *config) 2184 + { 2185 + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val); 2186 + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val); 2187 + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val); 2188 + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val); 2189 + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val); 2190 + clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); 2191 + clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val); 2192 + clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val); 2193 + 2194 + regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY); 2195 + 2196 + regmap_update_bits(regmap, PLL_MODE(pll), 2197 + PLL_RESET_N | PLL_BYPASSNL | PLL_OUTCTRL, 2198 + PLL_RESET_N | PLL_BYPASSNL); 2199 + } 2200 + EXPORT_SYMBOL_GPL(clk_rivian_evo_pll_configure); 2201 + 2202 + static unsigned long clk_rivian_evo_pll_recalc_rate(struct clk_hw *hw, 2203 + unsigned long parent_rate) 2204 + { 2205 + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); 2206 + u32 l; 2207 + 2208 + regmap_read(pll->clkr.regmap, PLL_L_VAL(pll), &l); 2209 + 2210 + return parent_rate * l; 2211 + } 2212 + 2213 + static long clk_rivian_evo_pll_round_rate(struct clk_hw *hw, unsigned long rate, 2214 + unsigned long *prate) 2215 + { 2216 + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); 2217 + unsigned long min_freq, max_freq; 2218 + u32 l; 2219 + u64 a; 2220 + 2221 + rate = alpha_pll_round_rate(rate, *prate, &l, &a, 0); 2222 + if (!pll->vco_table || alpha_pll_find_vco(pll, rate)) 2223 + return rate; 2224 + 2225 + min_freq = pll->vco_table[0].min_freq; 2226 + max_freq = pll->vco_table[pll->num_vco - 1].max_freq; 2227 + 2228 + return clamp(rate, min_freq, max_freq); 2229 + } 2230 + 2231 + const struct clk_ops clk_alpha_pll_rivian_evo_ops = { 2232 + .enable = alpha_pll_lucid_5lpe_enable, 2233 + .disable = alpha_pll_lucid_5lpe_disable, 2234 + .is_enabled = clk_trion_pll_is_enabled, 2235 + .recalc_rate = clk_rivian_evo_pll_recalc_rate, 2236 + .round_rate = clk_rivian_evo_pll_round_rate, 2237 + }; 2238 + EXPORT_SYMBOL_GPL(clk_alpha_pll_rivian_evo_ops);
+6
drivers/clk/qcom/clk-alpha-pll.h
··· 18 18 CLK_ALPHA_PLL_TYPE_AGERA, 19 19 CLK_ALPHA_PLL_TYPE_ZONDA, 20 20 CLK_ALPHA_PLL_TYPE_LUCID_EVO, 21 + CLK_ALPHA_PLL_TYPE_RIVIAN_EVO, 21 22 CLK_ALPHA_PLL_TYPE_MAX, 22 23 }; 23 24 ··· 158 157 extern const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops; 159 158 extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops; 160 159 160 + extern const struct clk_ops clk_alpha_pll_rivian_evo_ops; 161 + #define clk_alpha_pll_postdiv_rivian_evo_ops clk_alpha_pll_postdiv_fabia_ops 162 + 161 163 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 162 164 const struct alpha_pll_config *config); 163 165 void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, ··· 176 172 const struct alpha_pll_config *config); 177 173 void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 178 174 const struct alpha_pll_config *config); 175 + void clk_rivian_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 176 + const struct alpha_pll_config *config); 179 177 180 178 #endif