From e429572fa3de392aa3421b4b741eac5096a98ff7 Mon Sep 17 00:00:00 2001 From: Amit Nischal Date: Thu, 9 Mar 2017 17:36:05 +0530 Subject: clk: qcom: Add clk_ops to support runtime frequencies for esc clock Some of the display panels requires multiple clock frequencies to be derived runtime from the sources for its operation. Add support for the same by adding esc clk_ops to calculate the desired frequency at run time. Change-Id: Ie3ec84bb1927f5313c887344368dceffb06035be Signed-off-by: Amit Nischal --- drivers/clk/qcom/clk-rcg.h | 3 +- drivers/clk/qcom/clk-rcg2.c | 70 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index 58fbd07e6f15..0bcada9aac5d 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2013, 2016-2017, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -192,5 +192,6 @@ extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_gfx3d_src_ops; extern const struct clk_ops clk_dp_ops; +extern const struct clk_ops clk_esc_ops; #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 632d0f4ac9c1..ff0c8327fabe 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -1349,3 +1349,73 @@ const struct clk_ops clk_gfx3d_src_ops = { .list_registers = clk_rcg2_list_registers, }; EXPORT_SYMBOL_GPL(clk_gfx3d_src_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); -- cgit v1.2.3 From 2bb28272df7b753fd6479829b1fe9d92ea48943e Mon Sep 17 00:00:00 2001 From: Amit Nischal Date: Fri, 10 Mar 2017 16:46:36 +0530 Subject: clk: qcom: Update ops for esc clock source Some of the display panels requires various escape clock frequencies for its operation. Add support for the same by update esc clock ops to clk_esc_ops. Change-Id: I50cb79863cfdf880ba72e73a98905ecd87a08474 Signed-off-by: Amit Nischal --- drivers/clk/qcom/mmcc-sdm660.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clk/qcom/mmcc-sdm660.c b/drivers/clk/qcom/mmcc-sdm660.c index 0bf7ef05ed06..910c36c65b6a 100644 --- a/drivers/clk/qcom/mmcc-sdm660.c +++ b/drivers/clk/qcom/mmcc-sdm660.c @@ -978,12 +978,11 @@ static struct clk_rcg2 esc0_clk_src = { .mnd_width = 0, .hid_width = 5, .parent_map = mmcc_parent_map_1, - .freq_tbl = ftbl_dp_aux_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "esc0_clk_src", .parent_names = mmcc_parent_names_1, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_esc_ops, VDD_DIG_FMAX_MAP1( LOWER, 19200000), }, @@ -994,12 +993,11 @@ static struct clk_rcg2 esc1_clk_src = { .mnd_width = 0, .hid_width = 5, .parent_map = mmcc_parent_map_1, - .freq_tbl = ftbl_dp_aux_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "esc1_clk_src", .parent_names = mmcc_parent_names_1, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_esc_ops, VDD_DIG_FMAX_MAP1( LOWER, 19200000), }, -- cgit v1.2.3