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

clk: qcom: rcg2: add clk_rcg2_shared_floor_ops

Generally SDCC clocks use clk_rcg2_floor_ops, however on SAR2130P
platform it's recommended to use rcg2_shared_ops for all Root Clock
Generators to park them instead of disabling. Implement a mix of those,
clk_rcg2_shared_floor_ops.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://lore.kernel.org/r/20241027-sar2130p-clocks-v5-6-ecad2a1432ba@linaro.org
Signed-off-by: Bjorn Andersson <andersson@kernel.org>

authored by

Dmitry Baryshkov and committed by
Bjorn Andersson
aec8c0e2 f93cea43

+44 -5
+1
drivers/clk/qcom/clk-rcg.h
··· 198 198 extern const struct clk_ops clk_pixel_ops; 199 199 extern const struct clk_ops clk_gfx3d_ops; 200 200 extern const struct clk_ops clk_rcg2_shared_ops; 201 + extern const struct clk_ops clk_rcg2_shared_floor_ops; 201 202 extern const struct clk_ops clk_rcg2_shared_no_init_park_ops; 202 203 extern const struct clk_ops clk_dp_ops; 203 204
+43 -5
drivers/clk/qcom/clk-rcg2.c
··· 1186 1186 return clk_rcg2_clear_force_enable(hw); 1187 1187 } 1188 1188 1189 - static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate, 1190 - unsigned long parent_rate) 1189 + static int __clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate, 1190 + unsigned long parent_rate, 1191 + enum freq_policy policy) 1191 1192 { 1192 1193 struct clk_rcg2 *rcg = to_clk_rcg2(hw); 1193 1194 const struct freq_tbl *f; 1194 1195 1195 - f = qcom_find_freq(rcg->freq_tbl, rate); 1196 - if (!f) 1196 + switch (policy) { 1197 + case FLOOR: 1198 + f = qcom_find_freq_floor(rcg->freq_tbl, rate); 1199 + break; 1200 + case CEIL: 1201 + f = qcom_find_freq(rcg->freq_tbl, rate); 1202 + break; 1203 + default: 1197 1204 return -EINVAL; 1205 + } 1198 1206 1199 1207 /* 1200 1208 * In case clock is disabled, update the M, N and D registers, cache ··· 1215 1207 return clk_rcg2_shared_force_enable_clear(hw, f); 1216 1208 } 1217 1209 1210 + static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate, 1211 + unsigned long parent_rate) 1212 + { 1213 + return __clk_rcg2_shared_set_rate(hw, rate, parent_rate, CEIL); 1214 + } 1215 + 1218 1216 static int clk_rcg2_shared_set_rate_and_parent(struct clk_hw *hw, 1219 1217 unsigned long rate, unsigned long parent_rate, u8 index) 1220 1218 { 1221 - return clk_rcg2_shared_set_rate(hw, rate, parent_rate); 1219 + return __clk_rcg2_shared_set_rate(hw, rate, parent_rate, CEIL); 1220 + } 1221 + 1222 + static int clk_rcg2_shared_set_floor_rate(struct clk_hw *hw, unsigned long rate, 1223 + unsigned long parent_rate) 1224 + { 1225 + return __clk_rcg2_shared_set_rate(hw, rate, parent_rate, FLOOR); 1226 + } 1227 + 1228 + static int clk_rcg2_shared_set_floor_rate_and_parent(struct clk_hw *hw, 1229 + unsigned long rate, unsigned long parent_rate, u8 index) 1230 + { 1231 + return __clk_rcg2_shared_set_rate(hw, rate, parent_rate, FLOOR); 1222 1232 } 1223 1233 1224 1234 static int clk_rcg2_shared_enable(struct clk_hw *hw) ··· 1373 1347 .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent, 1374 1348 }; 1375 1349 EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); 1350 + 1351 + const struct clk_ops clk_rcg2_shared_floor_ops = { 1352 + .enable = clk_rcg2_shared_enable, 1353 + .disable = clk_rcg2_shared_disable, 1354 + .get_parent = clk_rcg2_shared_get_parent, 1355 + .set_parent = clk_rcg2_shared_set_parent, 1356 + .recalc_rate = clk_rcg2_shared_recalc_rate, 1357 + .determine_rate = clk_rcg2_determine_floor_rate, 1358 + .set_rate = clk_rcg2_shared_set_floor_rate, 1359 + .set_rate_and_parent = clk_rcg2_shared_set_floor_rate_and_parent, 1360 + }; 1361 + EXPORT_SYMBOL_GPL(clk_rcg2_shared_floor_ops); 1376 1362 1377 1363 static int clk_rcg2_shared_no_init_park(struct clk_hw *hw) 1378 1364 {