diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index a07deb902577..9e5c0b6f7a0e 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -307,7 +307,18 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) { u32 cfg, mask, old_cfg; struct clk_hw *hw = &rcg->clkr.hw; - int ret, index = qcom_find_src_index(hw, rcg->parent_map, f->src); + int ret, index; + + /* + * In case the frequency table of cxo_f is used, the src in parent_map + * and the source in cxo_f.src could be different. Update the index to + * '0' since it's assumed that CXO is always fed to port 0 of RCGs HLOS + * controls. + */ + if (f == &cxo_f) + index = 0; + else + index = qcom_find_src_index(hw, rcg->parent_map, f->src); if (index < 0) return index; @@ -507,6 +518,15 @@ static int clk_rcg2_enable(struct clk_hw *hw) if (!f) return -EINVAL; + /* + * If CXO is not listed as a supported frequency in the frequency + * table, the above API would return the lowest supported frequency + * instead. This will lead to incorrect configuration of the RCG. + * Check if the RCG rate is CXO and configure it accordingly. + */ + if (rate == cxo_f.freq) + f = &cxo_f; + clk_rcg_set_force_enable(hw); clk_rcg2_configure(rcg, f); clk_rcg_clear_force_enable(hw);