root/drivers/clk/qcom/clk-regmap-divider.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_clk_regmap_div
  2. div_round_ro_rate
  3. div_round_rate
  4. div_set_rate
  5. div_recalc_rate

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (c) 2014, The Linux Foundation. All rights reserved.
   4  */
   5 
   6 #include <linux/kernel.h>
   7 #include <linux/bitops.h>
   8 #include <linux/regmap.h>
   9 #include <linux/export.h>
  10 
  11 #include "clk-regmap-divider.h"
  12 
  13 static inline struct clk_regmap_div *to_clk_regmap_div(struct clk_hw *hw)
  14 {
  15         return container_of(to_clk_regmap(hw), struct clk_regmap_div, clkr);
  16 }
  17 
  18 static long div_round_ro_rate(struct clk_hw *hw, unsigned long rate,
  19                               unsigned long *prate)
  20 {
  21         struct clk_regmap_div *divider = to_clk_regmap_div(hw);
  22         struct clk_regmap *clkr = &divider->clkr;
  23         u32 val;
  24 
  25         regmap_read(clkr->regmap, divider->reg, &val);
  26         val >>= divider->shift;
  27         val &= BIT(divider->width) - 1;
  28 
  29         return divider_ro_round_rate(hw, rate, prate, NULL, divider->width,
  30                                      CLK_DIVIDER_ROUND_CLOSEST, val);
  31 }
  32 
  33 static long div_round_rate(struct clk_hw *hw, unsigned long rate,
  34                            unsigned long *prate)
  35 {
  36         struct clk_regmap_div *divider = to_clk_regmap_div(hw);
  37 
  38         return divider_round_rate(hw, rate, prate, NULL, divider->width,
  39                                   CLK_DIVIDER_ROUND_CLOSEST);
  40 }
  41 
  42 static int div_set_rate(struct clk_hw *hw, unsigned long rate,
  43                         unsigned long parent_rate)
  44 {
  45         struct clk_regmap_div *divider = to_clk_regmap_div(hw);
  46         struct clk_regmap *clkr = &divider->clkr;
  47         u32 div;
  48 
  49         div = divider_get_val(rate, parent_rate, NULL, divider->width,
  50                               CLK_DIVIDER_ROUND_CLOSEST);
  51 
  52         return regmap_update_bits(clkr->regmap, divider->reg,
  53                                   (BIT(divider->width) - 1) << divider->shift,
  54                                   div << divider->shift);
  55 }
  56 
  57 static unsigned long div_recalc_rate(struct clk_hw *hw,
  58                                      unsigned long parent_rate)
  59 {
  60         struct clk_regmap_div *divider = to_clk_regmap_div(hw);
  61         struct clk_regmap *clkr = &divider->clkr;
  62         u32 div;
  63 
  64         regmap_read(clkr->regmap, divider->reg, &div);
  65         div >>= divider->shift;
  66         div &= BIT(divider->width) - 1;
  67 
  68         return divider_recalc_rate(hw, parent_rate, div, NULL,
  69                                    CLK_DIVIDER_ROUND_CLOSEST, divider->width);
  70 }
  71 
  72 const struct clk_ops clk_regmap_div_ops = {
  73         .round_rate = div_round_rate,
  74         .set_rate = div_set_rate,
  75         .recalc_rate = div_recalc_rate,
  76 };
  77 EXPORT_SYMBOL_GPL(clk_regmap_div_ops);
  78 
  79 const struct clk_ops clk_regmap_div_ro_ops = {
  80         .round_rate = div_round_ro_rate,
  81         .recalc_rate = div_recalc_rate,
  82 };
  83 EXPORT_SYMBOL_GPL(clk_regmap_div_ro_ops);

/* [<][>][^][v][top][bottom][index][help] */