diff options
Diffstat (limited to 'drivers/clk/imx')
-rw-r--r-- | drivers/clk/imx/clk-busy.c | 8 | ||||
-rw-r--r-- | drivers/clk/imx/clk-composite-8m.c | 16 | ||||
-rw-r--r-- | drivers/clk/imx/clk-composite-93.c | 7 | ||||
-rw-r--r-- | drivers/clk/imx/clk-cpu.c | 10 | ||||
-rw-r--r-- | drivers/clk/imx/clk-fixup-div.c | 10 | ||||
-rw-r--r-- | drivers/clk/imx/clk-fixup-mux.c | 2 | ||||
-rw-r--r-- | drivers/clk/imx/clk-frac-pll.c | 20 | ||||
-rw-r--r-- | drivers/clk/imx/clk-fracn-gppll.c | 17 | ||||
-rw-r--r-- | drivers/clk/imx/clk-gate-exclusive.c | 2 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx5.c | 2 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8-acm.c | 2 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8qxp-lpcg.c | 1 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx95-blk-ctl.c | 95 | ||||
-rw-r--r-- | drivers/clk/imx/clk-pfd.c | 18 | ||||
-rw-r--r-- | drivers/clk/imx/clk-pll14xx.c | 29 | ||||
-rw-r--r-- | drivers/clk/imx/clk-pllv2.c | 23 | ||||
-rw-r--r-- | drivers/clk/imx/clk-pllv3.c | 72 | ||||
-rw-r--r-- | drivers/clk/imx/clk-pllv4.c | 29 | ||||
-rw-r--r-- | drivers/clk/imx/clk-scu.c | 39 |
19 files changed, 226 insertions, 176 deletions
diff --git a/drivers/clk/imx/clk-busy.c b/drivers/clk/imx/clk-busy.c index f163df952ccc..eb27c6fee359 100644 --- a/drivers/clk/imx/clk-busy.c +++ b/drivers/clk/imx/clk-busy.c @@ -46,12 +46,12 @@ static unsigned long clk_busy_divider_recalc_rate(struct clk_hw *hw, return busy->div_ops->recalc_rate(&busy->div.hw, parent_rate); } -static long clk_busy_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_busy_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_busy_divider *busy = to_clk_busy_divider(hw); - return busy->div_ops->round_rate(&busy->div.hw, rate, prate); + return busy->div_ops->determine_rate(&busy->div.hw, req); } static int clk_busy_divider_set_rate(struct clk_hw *hw, unsigned long rate, @@ -69,7 +69,7 @@ static int clk_busy_divider_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_busy_divider_ops = { .recalc_rate = clk_busy_divider_recalc_rate, - .round_rate = clk_busy_divider_round_rate, + .determine_rate = clk_busy_divider_determine_rate, .set_rate = clk_busy_divider_set_rate, }; diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index f187582ba491..1467d0a1b934 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -73,21 +73,6 @@ static int imx8m_clk_composite_compute_dividers(unsigned long rate, return ret; } -static long imx8m_clk_composite_divider_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *prate) -{ - int prediv_value; - int div_value; - - imx8m_clk_composite_compute_dividers(rate, *prate, - &prediv_value, &div_value); - rate = DIV_ROUND_UP(*prate, prediv_value); - - return DIV_ROUND_UP(rate, div_value); - -} - static int imx8m_clk_composite_divider_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) @@ -153,7 +138,6 @@ static int imx8m_divider_determine_rate(struct clk_hw *hw, static const struct clk_ops imx8m_clk_composite_divider_ops = { .recalc_rate = imx8m_clk_composite_divider_recalc_rate, - .round_rate = imx8m_clk_composite_divider_round_rate, .set_rate = imx8m_clk_composite_divider_set_rate, .determine_rate = imx8m_divider_determine_rate, }; diff --git a/drivers/clk/imx/clk-composite-93.c b/drivers/clk/imx/clk-composite-93.c index 6c6c5a30f328..513d74a39d3b 100644 --- a/drivers/clk/imx/clk-composite-93.c +++ b/drivers/clk/imx/clk-composite-93.c @@ -98,12 +98,6 @@ imx93_clk_composite_divider_recalc_rate(struct clk_hw *hw, unsigned long parent_ return clk_divider_ops.recalc_rate(hw, parent_rate); } -static long -imx93_clk_composite_divider_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) -{ - return clk_divider_ops.round_rate(hw, rate, prate); -} - static int imx93_clk_composite_divider_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { @@ -141,7 +135,6 @@ static int imx93_clk_composite_divider_set_rate(struct clk_hw *hw, unsigned long static const struct clk_ops imx93_clk_composite_divider_ops = { .recalc_rate = imx93_clk_composite_divider_recalc_rate, - .round_rate = imx93_clk_composite_divider_round_rate, .determine_rate = imx93_clk_composite_divider_determine_rate, .set_rate = imx93_clk_composite_divider_set_rate, }; diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c index cb6ca4cf0535..43637cb61693 100644 --- a/drivers/clk/imx/clk-cpu.c +++ b/drivers/clk/imx/clk-cpu.c @@ -30,12 +30,14 @@ static unsigned long clk_cpu_recalc_rate(struct clk_hw *hw, return clk_get_rate(cpu->div); } -static long clk_cpu_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_cpu_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_cpu *cpu = to_clk_cpu(hw); - return clk_round_rate(cpu->pll, rate); + req->rate = clk_round_rate(cpu->pll, req->rate); + + return 0; } static int clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate, @@ -66,7 +68,7 @@ static int clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_cpu_ops = { .recalc_rate = clk_cpu_recalc_rate, - .round_rate = clk_cpu_round_rate, + .determine_rate = clk_cpu_determine_rate, .set_rate = clk_cpu_set_rate, }; diff --git a/drivers/clk/imx/clk-fixup-div.c b/drivers/clk/imx/clk-fixup-div.c index 100ca828b052..aa6addbeb5a8 100644 --- a/drivers/clk/imx/clk-fixup-div.c +++ b/drivers/clk/imx/clk-fixup-div.c @@ -18,7 +18,7 @@ * @fixup: a hook to fixup the write value * * The imx fixup divider clock is a subclass of basic clk_divider - * with an addtional fixup hook. + * with an additional fixup hook. */ struct clk_fixup_div { struct clk_divider divider; @@ -41,12 +41,12 @@ static unsigned long clk_fixup_div_recalc_rate(struct clk_hw *hw, return fixup_div->ops->recalc_rate(&fixup_div->divider.hw, parent_rate); } -static long clk_fixup_div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_fixup_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw); - return fixup_div->ops->round_rate(&fixup_div->divider.hw, rate, prate); + return fixup_div->ops->determine_rate(&fixup_div->divider.hw, req); } static int clk_fixup_div_set_rate(struct clk_hw *hw, unsigned long rate, @@ -81,7 +81,7 @@ static int clk_fixup_div_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_fixup_div_ops = { .recalc_rate = clk_fixup_div_recalc_rate, - .round_rate = clk_fixup_div_round_rate, + .determine_rate = clk_fixup_div_determine_rate, .set_rate = clk_fixup_div_set_rate, }; diff --git a/drivers/clk/imx/clk-fixup-mux.c b/drivers/clk/imx/clk-fixup-mux.c index b48701864ef0..418ac9fe2c26 100644 --- a/drivers/clk/imx/clk-fixup-mux.c +++ b/drivers/clk/imx/clk-fixup-mux.c @@ -17,7 +17,7 @@ * @fixup: a hook to fixup the write value * * The imx fixup multiplexer clock is a subclass of basic clk_mux - * with an addtional fixup hook. + * with an additional fixup hook. */ struct clk_fixup_mux { struct clk_mux mux; diff --git a/drivers/clk/imx/clk-frac-pll.c b/drivers/clk/imx/clk-frac-pll.c index c703056fae85..eb668faaa38f 100644 --- a/drivers/clk/imx/clk-frac-pll.c +++ b/drivers/clk/imx/clk-frac-pll.c @@ -119,19 +119,19 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, return rate; } -static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - u64 parent_rate = *prate; + u64 parent_rate = req->best_parent_rate; u32 divff, divfi; u64 temp64; parent_rate *= 8; - rate *= 2; - temp64 = rate; + req->rate *= 2; + temp64 = req->rate; do_div(temp64, parent_rate); divfi = temp64; - temp64 = rate - divfi * parent_rate; + temp64 = req->rate - divfi * parent_rate; temp64 *= PLL_FRAC_DENOM; do_div(temp64, parent_rate); divff = temp64; @@ -140,9 +140,11 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, temp64 *= divff; do_div(temp64, PLL_FRAC_DENOM); - rate = parent_rate * divfi + temp64; + req->rate = parent_rate * divfi + temp64; + + req->rate = req->rate / 2; - return rate / 2; + return 0; } /* @@ -198,7 +200,7 @@ static const struct clk_ops clk_frac_pll_ops = { .unprepare = clk_pll_unprepare, .is_prepared = clk_pll_is_prepared, .recalc_rate = clk_pll_recalc_rate, - .round_rate = clk_pll_round_rate, + .determine_rate = clk_pll_determine_rate, .set_rate = clk_pll_set_rate, }; diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c index 85771afd4698..090d60867250 100644 --- a/drivers/clk/imx/clk-fracn-gppll.c +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -134,8 +134,8 @@ imx_get_pll_settings(struct clk_fracn_gppll *pll, unsigned long rate) return NULL; } -static long clk_fracn_gppll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_fracn_gppll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_fracn_gppll *pll = to_clk_fracn_gppll(hw); const struct imx_fracn_gppll_rate_table *rate_table = pll->rate_table; @@ -143,11 +143,16 @@ static long clk_fracn_gppll_round_rate(struct clk_hw *hw, unsigned long rate, /* Assuming rate_table is in descending order */ for (i = 0; i < pll->rate_count; i++) - if (rate >= rate_table[i].rate) - return rate_table[i].rate; + if (req->rate >= rate_table[i].rate) { + req->rate = rate_table[i].rate; + + return 0; + } /* return minimum supported value */ - return rate_table[pll->rate_count - 1].rate; + req->rate = rate_table[pll->rate_count - 1].rate; + + return 0; } static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) @@ -345,7 +350,7 @@ static const struct clk_ops clk_fracn_gppll_ops = { .unprepare = clk_fracn_gppll_unprepare, .is_prepared = clk_fracn_gppll_is_prepared, .recalc_rate = clk_fracn_gppll_recalc_rate, - .round_rate = clk_fracn_gppll_round_rate, + .determine_rate = clk_fracn_gppll_determine_rate, .set_rate = clk_fracn_gppll_set_rate, }; diff --git a/drivers/clk/imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c index 77342893bb71..7017e9d4e188 100644 --- a/drivers/clk/imx/clk-gate-exclusive.c +++ b/drivers/clk/imx/clk-gate-exclusive.c @@ -18,7 +18,7 @@ * gate clock * * The imx exclusive gate clock is a subclass of basic clk_gate - * with an addtional mask to indicate which other gate bits in the same + * with an additional mask to indicate which other gate bits in the same * register is mutually exclusive to this gate clock. */ struct clk_gate_exclusive { diff --git a/drivers/clk/imx/clk-imx5.c b/drivers/clk/imx/clk-imx5.c index b82044911603..9c5f489b3975 100644 --- a/drivers/clk/imx/clk-imx5.c +++ b/drivers/clk/imx/clk-imx5.c @@ -454,7 +454,7 @@ static void __init mx51_clocks_init(struct device_node *np) * longer supported. Set to one for better power saving. * * The effect of not setting these bits is that MIPI clocks can't be - * enabled without the IPU clock being enabled aswell. + * enabled without the IPU clock being enabled as well. */ val = readl(MXC_CCM_CCDR); val |= 1 << 18; diff --git a/drivers/clk/imx/clk-imx8-acm.c b/drivers/clk/imx/clk-imx8-acm.c index c169fe53a35f..790f7e44b11e 100644 --- a/drivers/clk/imx/clk-imx8-acm.c +++ b/drivers/clk/imx/clk-imx8-acm.c @@ -22,7 +22,7 @@ * struct clk_imx_acm_pm_domains - structure for multi power domain * @pd_dev: power domain device * @pd_dev_link: power domain device link - * @num_domains: power domain nummber + * @num_domains: power domain number */ struct clk_imx_acm_pm_domains { struct device **pd_dev; diff --git a/drivers/clk/imx/clk-imx8qxp-lpcg.c b/drivers/clk/imx/clk-imx8qxp-lpcg.c index d0ccaa040225..1dae3410ee99 100644 --- a/drivers/clk/imx/clk-imx8qxp-lpcg.c +++ b/drivers/clk/imx/clk-imx8qxp-lpcg.c @@ -267,7 +267,6 @@ static int imx_lpcg_parse_clks_from_dt(struct platform_device *pdev, if (ret) goto unreg; - pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_put_autosuspend(&pdev->dev); return 0; diff --git a/drivers/clk/imx/clk-imx95-blk-ctl.c b/drivers/clk/imx/clk-imx95-blk-ctl.c index 25974947ad0c..7e88877a6245 100644 --- a/drivers/clk/imx/clk-imx95-blk-ctl.c +++ b/drivers/clk/imx/clk-imx95-blk-ctl.c @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright 2024 NXP + * Copyright 2024-2025 NXP */ +#include <dt-bindings/clock/nxp,imx94-clock.h> #include <dt-bindings/clock/nxp,imx95-clock.h> #include <linux/clk.h> #include <linux/clk-provider.h> @@ -156,7 +157,7 @@ static const struct imx95_blk_ctl_dev_data camblk_dev_data = { .clk_reg_offset = 0, }; -static const struct imx95_blk_ctl_clk_dev_data lvds_clk_dev_data[] = { +static const struct imx95_blk_ctl_clk_dev_data imx95_lvds_clk_dev_data[] = { [IMX95_CLK_DISPMIX_LVDS_PHY_DIV] = { .name = "ldb_phy_div", .parent_names = (const char *[]){ "ldbpll", }, @@ -213,17 +214,21 @@ static const struct imx95_blk_ctl_clk_dev_data lvds_clk_dev_data[] = { }, }; -static const struct imx95_blk_ctl_dev_data lvds_csr_dev_data = { - .num_clks = ARRAY_SIZE(lvds_clk_dev_data), - .clk_dev_data = lvds_clk_dev_data, +static const struct imx95_blk_ctl_dev_data imx95_lvds_csr_dev_data = { + .num_clks = ARRAY_SIZE(imx95_lvds_clk_dev_data), + .clk_dev_data = imx95_lvds_clk_dev_data, .clk_reg_offset = 0, }; -static const struct imx95_blk_ctl_clk_dev_data dispmix_csr_clk_dev_data[] = { +static const char * const imx95_disp_engine_parents[] = { + "videopll1", "dsi_pll", "ldb_pll_div7" +}; + +static const struct imx95_blk_ctl_clk_dev_data imx95_dispmix_csr_clk_dev_data[] = { [IMX95_CLK_DISPMIX_ENG0_SEL] = { .name = "disp_engine0_sel", - .parent_names = (const char *[]){"videopll1", "dsi_pll", "ldb_pll_div7", }, - .num_parents = 4, + .parent_names = imx95_disp_engine_parents, + .num_parents = ARRAY_SIZE(imx95_disp_engine_parents), .reg = 0, .bit_idx = 0, .bit_width = 2, @@ -232,8 +237,8 @@ static const struct imx95_blk_ctl_clk_dev_data dispmix_csr_clk_dev_data[] = { }, [IMX95_CLK_DISPMIX_ENG1_SEL] = { .name = "disp_engine1_sel", - .parent_names = (const char *[]){"videopll1", "dsi_pll", "ldb_pll_div7", }, - .num_parents = 4, + .parent_names = imx95_disp_engine_parents, + .num_parents = ARRAY_SIZE(imx95_disp_engine_parents), .reg = 0, .bit_idx = 2, .bit_width = 2, @@ -242,9 +247,9 @@ static const struct imx95_blk_ctl_clk_dev_data dispmix_csr_clk_dev_data[] = { } }; -static const struct imx95_blk_ctl_dev_data dispmix_csr_dev_data = { - .num_clks = ARRAY_SIZE(dispmix_csr_clk_dev_data), - .clk_dev_data = dispmix_csr_clk_dev_data, +static const struct imx95_blk_ctl_dev_data imx95_dispmix_csr_dev_data = { + .num_clks = ARRAY_SIZE(imx95_dispmix_csr_clk_dev_data), + .clk_dev_data = imx95_dispmix_csr_clk_dev_data, .clk_reg_offset = 0, }; @@ -296,6 +301,51 @@ static const struct imx95_blk_ctl_dev_data hsio_blk_ctl_dev_data = { .clk_reg_offset = 0, }; +static const struct imx95_blk_ctl_clk_dev_data imx94_lvds_clk_dev_data[] = { + [IMX94_CLK_DISPMIX_LVDS_CLK_GATE] = { + .name = "lvds_clk_gate", + .parent_names = (const char *[]){ "ldbpll", }, + .num_parents = 1, + .reg = 0, + .bit_idx = 1, + .bit_width = 1, + .type = CLK_GATE, + .flags = CLK_SET_RATE_PARENT, + .flags2 = CLK_GATE_SET_TO_DISABLE, + }, +}; + +static const struct imx95_blk_ctl_dev_data imx94_lvds_csr_dev_data = { + .num_clks = ARRAY_SIZE(imx94_lvds_clk_dev_data), + .clk_dev_data = imx94_lvds_clk_dev_data, + .clk_reg_offset = 0, + .rpm_enabled = true, +}; + +static const char * const imx94_disp_engine_parents[] = { + "disppix", "ldb_pll_div7" +}; + +static const struct imx95_blk_ctl_clk_dev_data imx94_dispmix_csr_clk_dev_data[] = { + [IMX94_CLK_DISPMIX_CLK_SEL] = { + .name = "disp_clk_sel", + .parent_names = imx94_disp_engine_parents, + .num_parents = ARRAY_SIZE(imx94_disp_engine_parents), + .reg = 0, + .bit_idx = 1, + .bit_width = 1, + .type = CLK_MUX, + .flags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, + }, +}; + +static const struct imx95_blk_ctl_dev_data imx94_dispmix_csr_dev_data = { + .num_clks = ARRAY_SIZE(imx94_dispmix_csr_clk_dev_data), + .clk_dev_data = imx94_dispmix_csr_clk_dev_data, + .clk_reg_offset = 0, + .rpm_enabled = true, +}; + static int imx95_bc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -338,8 +388,10 @@ static int imx95_bc_probe(struct platform_device *pdev) if (!clk_hw_data) return -ENOMEM; - if (bc_data->rpm_enabled) - pm_runtime_enable(&pdev->dev); + if (bc_data->rpm_enabled) { + devm_pm_runtime_enable(&pdev->dev); + pm_runtime_resume_and_get(&pdev->dev); + } clk_hw_data->num = bc_data->num_clks; hws = clk_hw_data->hws; @@ -379,8 +431,10 @@ static int imx95_bc_probe(struct platform_device *pdev) goto cleanup; } - if (pm_runtime_enabled(bc->dev)) + if (pm_runtime_enabled(bc->dev)) { + pm_runtime_put_sync(&pdev->dev); clk_disable_unprepare(bc->clk_apb); + } return 0; @@ -391,9 +445,6 @@ cleanup: clk_hw_unregister(hws[i]); } - if (bc_data->rpm_enabled) - pm_runtime_disable(&pdev->dev); - return ret; } @@ -462,10 +513,12 @@ static const struct dev_pm_ops imx95_bc_pm_ops = { }; static const struct of_device_id imx95_bc_of_match[] = { + { .compatible = "nxp,imx94-display-csr", .data = &imx94_dispmix_csr_dev_data }, + { .compatible = "nxp,imx94-lvds-csr", .data = &imx94_lvds_csr_dev_data }, { .compatible = "nxp,imx95-camera-csr", .data = &camblk_dev_data }, { .compatible = "nxp,imx95-display-master-csr", }, - { .compatible = "nxp,imx95-lvds-csr", .data = &lvds_csr_dev_data }, - { .compatible = "nxp,imx95-display-csr", .data = &dispmix_csr_dev_data }, + { .compatible = "nxp,imx95-display-csr", .data = &imx95_dispmix_csr_dev_data }, + { .compatible = "nxp,imx95-lvds-csr", .data = &imx95_lvds_csr_dev_data }, { .compatible = "nxp,imx95-hsio-blk-ctl", .data = &hsio_blk_ctl_dev_data }, { .compatible = "nxp,imx95-vpu-csr", .data = &vpublk_dev_data }, { .compatible = "nxp,imx95-netcmix-blk-ctrl", .data = &netcmix_dev_data}, diff --git a/drivers/clk/imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c index 5cf0149dfa15..31220fa7882b 100644 --- a/drivers/clk/imx/clk-pfd.c +++ b/drivers/clk/imx/clk-pfd.c @@ -62,24 +62,26 @@ static unsigned long clk_pfd_recalc_rate(struct clk_hw *hw, return tmp; } -static long clk_pfd_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pfd_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - u64 tmp = *prate; + u64 tmp = req->best_parent_rate; u8 frac; - tmp = tmp * 18 + rate / 2; - do_div(tmp, rate); + tmp = tmp * 18 + req->rate / 2; + do_div(tmp, req->rate); frac = tmp; if (frac < 12) frac = 12; else if (frac > 35) frac = 35; - tmp = *prate; + tmp = req->best_parent_rate; tmp *= 18; do_div(tmp, frac); - return tmp; + req->rate = tmp; + + return 0; } static int clk_pfd_set_rate(struct clk_hw *hw, unsigned long rate, @@ -117,7 +119,7 @@ static const struct clk_ops clk_pfd_ops = { .enable = clk_pfd_enable, .disable = clk_pfd_disable, .recalc_rate = clk_pfd_recalc_rate, - .round_rate = clk_pfd_round_rate, + .determine_rate = clk_pfd_determine_rate, .set_rate = clk_pfd_set_rate, .is_enabled = clk_pfd_is_enabled, }; diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index f290981ea13b..36d0e80b55b8 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -216,8 +216,8 @@ found: t->mdiv, t->kdiv); } -static long clk_pll1416x_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pll1416x_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_pll14xx *pll = to_clk_pll14xx(hw); const struct imx_pll14xx_rate_table *rate_table = pll->rate_table; @@ -225,22 +225,29 @@ static long clk_pll1416x_round_rate(struct clk_hw *hw, unsigned long rate, /* Assuming rate_table is in descending order */ for (i = 0; i < pll->rate_count; i++) - if (rate >= rate_table[i].rate) - return rate_table[i].rate; + if (req->rate >= rate_table[i].rate) { + req->rate = rate_table[i].rate; + + return 0; + } /* return minimum supported value */ - return rate_table[pll->rate_count - 1].rate; + req->rate = rate_table[pll->rate_count - 1].rate; + + return 0; } -static long clk_pll1443x_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pll1443x_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_pll14xx *pll = to_clk_pll14xx(hw); struct imx_pll14xx_rate_table t; - imx_pll14xx_calc_settings(pll, rate, *prate, &t); + imx_pll14xx_calc_settings(pll, req->rate, req->best_parent_rate, &t); + + req->rate = t.rate; - return t.rate; + return 0; } static unsigned long clk_pll14xx_recalc_rate(struct clk_hw *hw, @@ -470,7 +477,7 @@ static const struct clk_ops clk_pll1416x_ops = { .unprepare = clk_pll14xx_unprepare, .is_prepared = clk_pll14xx_is_prepared, .recalc_rate = clk_pll14xx_recalc_rate, - .round_rate = clk_pll1416x_round_rate, + .determine_rate = clk_pll1416x_determine_rate, .set_rate = clk_pll1416x_set_rate, }; @@ -483,7 +490,7 @@ static const struct clk_ops clk_pll1443x_ops = { .unprepare = clk_pll14xx_unprepare, .is_prepared = clk_pll14xx_is_prepared, .recalc_rate = clk_pll14xx_recalc_rate, - .round_rate = clk_pll1443x_round_rate, + .determine_rate = clk_pll1443x_determine_rate, .set_rate = clk_pll1443x_set_rate, }; diff --git a/drivers/clk/imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c index ff17f0664faa..bb497ad5e0ae 100644 --- a/drivers/clk/imx/clk-pllv2.c +++ b/drivers/clk/imx/clk-pllv2.c @@ -178,18 +178,25 @@ static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pllv2_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { u32 dp_op, dp_mfd, dp_mfn; int ret; - ret = __clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn); - if (ret) - return ret; + ret = __clk_pllv2_set_rate(req->rate, req->best_parent_rate, &dp_op, + &dp_mfd, &dp_mfn); + if (ret) { + req->rate = ret; - return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN, - dp_op, dp_mfd, dp_mfn); + return 0; + } + + req->rate = __clk_pllv2_recalc_rate(req->best_parent_rate, + MXC_PLL_DP_CTL_DPDCK0_2_EN, dp_op, + dp_mfd, dp_mfn); + + return 0; } static int clk_pllv2_prepare(struct clk_hw *hw) @@ -235,7 +242,7 @@ static const struct clk_ops clk_pllv2_ops = { .prepare = clk_pllv2_prepare, .unprepare = clk_pllv2_unprepare, .recalc_rate = clk_pllv2_recalc_rate, - .round_rate = clk_pllv2_round_rate, + .determine_rate = clk_pllv2_determine_rate, .set_rate = clk_pllv2_set_rate, }; diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c index 11fb238ee8f0..b99508367bcb 100644 --- a/drivers/clk/imx/clk-pllv3.c +++ b/drivers/clk/imx/clk-pllv3.c @@ -117,13 +117,14 @@ static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw, return (div == 1) ? parent_rate * 22 : parent_rate * 20; } -static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pllv3_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned long parent_rate = *prate; + unsigned long parent_rate = req->best_parent_rate; - return (rate >= parent_rate * 22) ? parent_rate * 22 : - parent_rate * 20; + req->rate = (req->rate >= parent_rate * 22) ? parent_rate * 22 : parent_rate * 20; + + return 0; } static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate, @@ -152,7 +153,7 @@ static const struct clk_ops clk_pllv3_ops = { .unprepare = clk_pllv3_unprepare, .is_prepared = clk_pllv3_is_prepared, .recalc_rate = clk_pllv3_recalc_rate, - .round_rate = clk_pllv3_round_rate, + .determine_rate = clk_pllv3_determine_rate, .set_rate = clk_pllv3_set_rate, }; @@ -165,21 +166,23 @@ static unsigned long clk_pllv3_sys_recalc_rate(struct clk_hw *hw, return parent_rate * div / 2; } -static long clk_pllv3_sys_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pllv3_sys_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned long parent_rate = *prate; + unsigned long parent_rate = req->best_parent_rate; unsigned long min_rate = parent_rate * 54 / 2; unsigned long max_rate = parent_rate * 108 / 2; u32 div; - if (rate > max_rate) - rate = max_rate; - else if (rate < min_rate) - rate = min_rate; - div = rate * 2 / parent_rate; + if (req->rate > max_rate) + req->rate = max_rate; + else if (req->rate < min_rate) + req->rate = min_rate; + div = req->rate * 2 / parent_rate; - return parent_rate * div / 2; + req->rate = parent_rate * div / 2; + + return 0; } static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate, @@ -207,7 +210,7 @@ static const struct clk_ops clk_pllv3_sys_ops = { .unprepare = clk_pllv3_unprepare, .is_prepared = clk_pllv3_is_prepared, .recalc_rate = clk_pllv3_sys_recalc_rate, - .round_rate = clk_pllv3_sys_round_rate, + .determine_rate = clk_pllv3_sys_determine_rate, .set_rate = clk_pllv3_sys_set_rate, }; @@ -226,10 +229,10 @@ static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw, return parent_rate * div + (unsigned long)temp64; } -static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pllv3_av_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned long parent_rate = *prate; + unsigned long parent_rate = req->best_parent_rate; unsigned long min_rate = parent_rate * 27; unsigned long max_rate = parent_rate * 54; u32 div; @@ -237,16 +240,16 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, u32 max_mfd = 0x3FFFFFFF; u64 temp64; - if (rate > max_rate) - rate = max_rate; - else if (rate < min_rate) - rate = min_rate; + if (req->rate > max_rate) + req->rate = max_rate; + else if (req->rate < min_rate) + req->rate = min_rate; if (parent_rate <= max_mfd) mfd = parent_rate; - div = rate / parent_rate; - temp64 = (u64) (rate - div * parent_rate); + div = req->rate / parent_rate; + temp64 = (u64) (req->rate - div * parent_rate); temp64 *= mfd; temp64 = div64_ul(temp64, parent_rate); mfn = temp64; @@ -255,7 +258,9 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, temp64 *= mfn; do_div(temp64, mfd); - return parent_rate * div + (unsigned long)temp64; + req->rate = parent_rate * div + (unsigned long)temp64; + + return 0; } static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, @@ -296,7 +301,7 @@ static const struct clk_ops clk_pllv3_av_ops = { .unprepare = clk_pllv3_unprepare, .is_prepared = clk_pllv3_is_prepared, .recalc_rate = clk_pllv3_av_recalc_rate, - .round_rate = clk_pllv3_av_round_rate, + .determine_rate = clk_pllv3_av_determine_rate, .set_rate = clk_pllv3_av_set_rate, }; @@ -355,12 +360,15 @@ static unsigned long clk_pllv3_vf610_recalc_rate(struct clk_hw *hw, return clk_pllv3_vf610_mf_to_rate(parent_rate, mf); } -static long clk_pllv3_vf610_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pllv3_vf610_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - struct clk_pllv3_vf610_mf mf = clk_pllv3_vf610_rate_to_mf(*prate, rate); + struct clk_pllv3_vf610_mf mf = clk_pllv3_vf610_rate_to_mf(req->best_parent_rate, + req->rate); + + req->rate = clk_pllv3_vf610_mf_to_rate(req->best_parent_rate, mf); - return clk_pllv3_vf610_mf_to_rate(*prate, mf); + return 0; } static int clk_pllv3_vf610_set_rate(struct clk_hw *hw, unsigned long rate, @@ -389,7 +397,7 @@ static const struct clk_ops clk_pllv3_vf610_ops = { .unprepare = clk_pllv3_unprepare, .is_prepared = clk_pllv3_is_prepared, .recalc_rate = clk_pllv3_vf610_recalc_rate, - .round_rate = clk_pllv3_vf610_round_rate, + .determine_rate = clk_pllv3_vf610_determine_rate, .set_rate = clk_pllv3_vf610_set_rate, }; diff --git a/drivers/clk/imx/clk-pllv4.c b/drivers/clk/imx/clk-pllv4.c index 9b136c951762..01d05b5d5438 100644 --- a/drivers/clk/imx/clk-pllv4.c +++ b/drivers/clk/imx/clk-pllv4.c @@ -95,11 +95,11 @@ static unsigned long clk_pllv4_recalc_rate(struct clk_hw *hw, return (parent_rate * mult) + (u32)temp64; } -static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_pllv4_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_pllv4 *pll = to_clk_pllv4(hw); - unsigned long parent_rate = *prate; + unsigned long parent_rate = req->best_parent_rate; unsigned long round_rate, i; u32 mfn, mfd = DEFAULT_MFD; bool found = false; @@ -107,7 +107,7 @@ static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate, u32 mult; if (pll->use_mult_range) { - temp64 = (u64)rate; + temp64 = (u64) req->rate; do_div(temp64, parent_rate); mult = temp64; if (mult >= pllv4_mult_range[1] && @@ -118,7 +118,7 @@ static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate, } else { for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) { round_rate = parent_rate * pllv4_mult_table[i]; - if (rate >= round_rate) { + if (req->rate >= round_rate) { found = true; break; } @@ -127,14 +127,16 @@ static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate, if (!found) { pr_warn("%s: unable to round rate %lu, parent rate %lu\n", - clk_hw_get_name(hw), rate, parent_rate); + clk_hw_get_name(hw), req->rate, parent_rate); + req->rate = 0; + return 0; } if (parent_rate <= MAX_MFD) mfd = parent_rate; - temp64 = (u64)(rate - round_rate); + temp64 = (u64)(req->rate - round_rate); temp64 *= mfd; do_div(temp64, parent_rate); mfn = temp64; @@ -145,14 +147,19 @@ static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate, * pair of mfn/mfd, we simply return the round_rate without using * the frac part. */ - if (mfn >= mfd) - return round_rate; + if (mfn >= mfd) { + req->rate = round_rate; + + return 0; + } temp64 = (u64)parent_rate; temp64 *= mfn; do_div(temp64, mfd); - return round_rate + (u32)temp64; + req->rate = round_rate + (u32)temp64; + + return 0; } static bool clk_pllv4_is_valid_mult(struct clk_pllv4 *pll, unsigned int mult) @@ -229,7 +236,7 @@ static void clk_pllv4_unprepare(struct clk_hw *hw) static const struct clk_ops clk_pllv4_ops = { .recalc_rate = clk_pllv4_recalc_rate, - .round_rate = clk_pllv4_round_rate, + .determine_rate = clk_pllv4_determine_rate, .set_rate = clk_pllv4_set_rate, .prepare = clk_pllv4_prepare, .unprepare = clk_pllv4_unprepare, diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index b27186aaf2a1..34c9dc1fb20e 100644 --- a/drivers/clk/imx/clk-scu.c +++ b/drivers/clk/imx/clk-scu.c @@ -269,24 +269,6 @@ static int clk_scu_determine_rate(struct clk_hw *hw, return 0; } -/* - * clk_scu_round_rate - Round clock rate for a SCU clock - * @hw: clock to round rate for - * @rate: rate to round - * @parent_rate: parent rate provided by common clock framework, not used - * - * Returns the current clock rate, or zero in failure. - */ -static long clk_scu_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - /* - * Assume we support all the requested rate and let the SCU firmware - * to handle the left work - */ - return rate; -} - static int clk_scu_atf_set_cpu_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -454,7 +436,7 @@ static const struct clk_ops clk_scu_ops = { static const struct clk_ops clk_scu_cpu_ops = { .recalc_rate = clk_scu_recalc_rate, - .round_rate = clk_scu_round_rate, + .determine_rate = clk_scu_determine_rate, .set_rate = clk_scu_atf_set_cpu_rate, .prepare = clk_scu_prepare, .unprepare = clk_scu_unprepare, @@ -462,7 +444,7 @@ static const struct clk_ops clk_scu_cpu_ops = { static const struct clk_ops clk_scu_pi_ops = { .recalc_rate = clk_scu_recalc_rate, - .round_rate = clk_scu_round_rate, + .determine_rate = clk_scu_determine_rate, .set_rate = clk_scu_set_rate, }; @@ -567,7 +549,6 @@ static int imx_clk_scu_probe(struct platform_device *pdev) if (!((clk->rsrc == IMX_SC_R_A35) || (clk->rsrc == IMX_SC_R_A53) || (clk->rsrc == IMX_SC_R_A72))) { - pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_put_autosuspend(&pdev->dev); } @@ -729,7 +710,7 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name, if (ret) goto put_device; - /* For API backwards compatiblilty, simply return NULL for success */ + /* For API backwards compatibility, simply return NULL for success */ return NULL; put_device: @@ -766,15 +747,15 @@ static unsigned long clk_gpr_div_scu_recalc_rate(struct clk_hw *hw, return err ? 0 : rate; } -static long clk_gpr_div_scu_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int clk_gpr_div_scu_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - if (rate < *prate) - rate = *prate / 2; + if (req->rate < req->best_parent_rate) + req->rate = req->best_parent_rate / 2; else - rate = *prate; + req->rate = req->best_parent_rate; - return rate; + return 0; } static int clk_gpr_div_scu_set_rate(struct clk_hw *hw, unsigned long rate, @@ -793,7 +774,7 @@ static int clk_gpr_div_scu_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_gpr_div_scu_ops = { .recalc_rate = clk_gpr_div_scu_recalc_rate, - .round_rate = clk_gpr_div_scu_round_rate, + .determine_rate = clk_gpr_div_scu_determine_rate, .set_rate = clk_gpr_div_scu_set_rate, }; |