Loading drivers/clk/qcom/clk-rcg.h +1 −0 Original line number Diff line number Diff line Loading @@ -174,6 +174,7 @@ extern const struct clk_ops clk_rcg2_shared_ops; extern const struct clk_ops clk_dp_ops; extern const struct clk_ops clk_rcg2_dependent_ops; extern const struct clk_ops clk_gfx3d_src_ops; extern const struct clk_ops clk_esc_ops; struct clk_rcg_dfs_data { struct clk_rcg2 *rcg; Loading drivers/clk/qcom/clk-rcg2.c +70 −0 Original line number Diff line number Diff line Loading @@ -1794,3 +1794,73 @@ const struct clk_ops clk_rcg2_dependent_ops = { .bus_vote = clk_debug_bus_vote, }; EXPORT_SYMBOL(clk_rcg2_dependent_ops); static int clk_esc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); unsigned long parent_rate, div; u32 mask = BIT(rcg->hid_width) - 1; struct clk_hw *p; unsigned long rate = req->rate; if (rate == 0) return -EINVAL; p = req->best_parent_hw; req->best_parent_rate = parent_rate = clk_hw_round_rate(p, rate); div = ((2 * parent_rate) / rate) - 1; div = min_t(u32, div, mask); req->rate = calc_rate(parent_rate, 0, 0, 0, div); return 0; } static int clk_esc_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); struct freq_tbl f = { 0 }; unsigned long div; int i, num_parents = clk_hw_get_num_parents(hw); u32 mask = BIT(rcg->hid_width) - 1; u32 cfg; div = ((2 * parent_rate) / rate) - 1; div = min_t(u32, div, mask); f.pre_div = div; regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg); cfg &= CFG_SRC_SEL_MASK; cfg >>= CFG_SRC_SEL_SHIFT; for (i = 0; i < num_parents; i++) { if (cfg == rcg->parent_map[i].cfg) { f.src = rcg->parent_map[i].src; return clk_rcg2_configure(rcg, &f); } } return -EINVAL; } static int clk_esc_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate, u8 index) { return clk_esc_set_rate(hw, rate, parent_rate); } const struct clk_ops clk_esc_ops = { .is_enabled = clk_rcg2_is_enabled, .get_parent = clk_rcg2_get_parent, .set_parent = clk_rcg2_set_parent, .recalc_rate = clk_rcg2_recalc_rate, .determine_rate = clk_esc_determine_rate, .set_rate = clk_esc_set_rate, .set_rate_and_parent = clk_esc_set_rate_and_parent, .list_registers = clk_rcg2_list_registers, }; EXPORT_SYMBOL(clk_esc_ops); Loading
drivers/clk/qcom/clk-rcg.h +1 −0 Original line number Diff line number Diff line Loading @@ -174,6 +174,7 @@ extern const struct clk_ops clk_rcg2_shared_ops; extern const struct clk_ops clk_dp_ops; extern const struct clk_ops clk_rcg2_dependent_ops; extern const struct clk_ops clk_gfx3d_src_ops; extern const struct clk_ops clk_esc_ops; struct clk_rcg_dfs_data { struct clk_rcg2 *rcg; Loading
drivers/clk/qcom/clk-rcg2.c +70 −0 Original line number Diff line number Diff line Loading @@ -1794,3 +1794,73 @@ const struct clk_ops clk_rcg2_dependent_ops = { .bus_vote = clk_debug_bus_vote, }; EXPORT_SYMBOL(clk_rcg2_dependent_ops); static int clk_esc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); unsigned long parent_rate, div; u32 mask = BIT(rcg->hid_width) - 1; struct clk_hw *p; unsigned long rate = req->rate; if (rate == 0) return -EINVAL; p = req->best_parent_hw; req->best_parent_rate = parent_rate = clk_hw_round_rate(p, rate); div = ((2 * parent_rate) / rate) - 1; div = min_t(u32, div, mask); req->rate = calc_rate(parent_rate, 0, 0, 0, div); return 0; } static int clk_esc_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); struct freq_tbl f = { 0 }; unsigned long div; int i, num_parents = clk_hw_get_num_parents(hw); u32 mask = BIT(rcg->hid_width) - 1; u32 cfg; div = ((2 * parent_rate) / rate) - 1; div = min_t(u32, div, mask); f.pre_div = div; regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg); cfg &= CFG_SRC_SEL_MASK; cfg >>= CFG_SRC_SEL_SHIFT; for (i = 0; i < num_parents; i++) { if (cfg == rcg->parent_map[i].cfg) { f.src = rcg->parent_map[i].src; return clk_rcg2_configure(rcg, &f); } } return -EINVAL; } static int clk_esc_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate, u8 index) { return clk_esc_set_rate(hw, rate, parent_rate); } const struct clk_ops clk_esc_ops = { .is_enabled = clk_rcg2_is_enabled, .get_parent = clk_rcg2_get_parent, .set_parent = clk_rcg2_set_parent, .recalc_rate = clk_rcg2_recalc_rate, .determine_rate = clk_esc_determine_rate, .set_rate = clk_esc_set_rate, .set_rate_and_parent = clk_esc_set_rate_and_parent, .list_registers = clk_rcg2_list_registers, }; EXPORT_SYMBOL(clk_esc_ops);