Loading drivers/clk/qcom/clk-rcg.h +2 −1 Original line number Diff line number Diff line /* * Copyright (c) 2013, 2016-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2013, 2016-2018, 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 Loading Loading @@ -185,6 +185,7 @@ extern const struct clk_ops clk_byte2_ops; extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_dp_ops; extern const struct clk_ops clk_esc_ops; extern int clk_rcg2_get_dfs_clock_rate(struct clk_rcg2 *clk, struct device *dev, u8 rcg_flags); Loading drivers/clk/qcom/clk-rcg2.c +70 −0 Original line number Diff line number Diff line Loading @@ -1191,6 +1191,76 @@ const struct clk_ops clk_gfx3d_ops = { }; EXPORT_SYMBOL_GPL(clk_gfx3d_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 = clk_rcg2_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); /* Common APIs to be used for DFS based RCGR */ static u8 clk_parent_index_pre_div_and_mode(struct clk_hw *hw, u32 offset, u32 *mode, u32 *pre_div) Loading drivers/clk/qcom/dispcc-sdm845.c +3 −5 Original line number Diff line number Diff line /* * Copyright (c) 2017, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -328,13 +328,12 @@ static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_0, .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "disp_cc_mdss_esc0_clk_src", .parent_names = disp_cc_parent_names_0, .num_parents = 4, .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, .ops = &clk_esc_ops, VDD_CX_FMAX_MAP1( MIN, 19200000), }, Loading @@ -345,13 +344,12 @@ static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = { .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_0, .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "disp_cc_mdss_esc1_clk_src", .parent_names = disp_cc_parent_names_0, .num_parents = 4, .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, .ops = &clk_esc_ops, VDD_CX_FMAX_MAP1( MIN, 19200000), }, Loading Loading
drivers/clk/qcom/clk-rcg.h +2 −1 Original line number Diff line number Diff line /* * Copyright (c) 2013, 2016-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2013, 2016-2018, 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 Loading Loading @@ -185,6 +185,7 @@ extern const struct clk_ops clk_byte2_ops; extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_dp_ops; extern const struct clk_ops clk_esc_ops; extern int clk_rcg2_get_dfs_clock_rate(struct clk_rcg2 *clk, struct device *dev, u8 rcg_flags); Loading
drivers/clk/qcom/clk-rcg2.c +70 −0 Original line number Diff line number Diff line Loading @@ -1191,6 +1191,76 @@ const struct clk_ops clk_gfx3d_ops = { }; EXPORT_SYMBOL_GPL(clk_gfx3d_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 = clk_rcg2_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); /* Common APIs to be used for DFS based RCGR */ static u8 clk_parent_index_pre_div_and_mode(struct clk_hw *hw, u32 offset, u32 *mode, u32 *pre_div) Loading
drivers/clk/qcom/dispcc-sdm845.c +3 −5 Original line number Diff line number Diff line /* * Copyright (c) 2017, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -328,13 +328,12 @@ static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_0, .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "disp_cc_mdss_esc0_clk_src", .parent_names = disp_cc_parent_names_0, .num_parents = 4, .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, .ops = &clk_esc_ops, VDD_CX_FMAX_MAP1( MIN, 19200000), }, Loading @@ -345,13 +344,12 @@ static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = { .mnd_width = 0, .hid_width = 5, .parent_map = disp_cc_parent_map_0, .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "disp_cc_mdss_esc1_clk_src", .parent_names = disp_cc_parent_names_0, .num_parents = 4, .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, .ops = &clk_esc_ops, VDD_CX_FMAX_MAP1( MIN, 19200000), }, Loading