root/drivers/clk/ux500/clk-sysctrl.c

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

DEFINITIONS

This source file includes following definitions.
  1. clk_sysctrl_prepare
  2. clk_sysctrl_unprepare
  3. clk_sysctrl_recalc_rate
  4. clk_sysctrl_set_parent
  5. clk_sysctrl_get_parent
  6. clk_reg_sysctrl
  7. clk_reg_sysctrl_gate
  8. clk_reg_sysctrl_gate_fixed_rate
  9. clk_reg_sysctrl_set_parent

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Sysctrl clock implementation for ux500 platform.
   4  *
   5  * Copyright (C) 2013 ST-Ericsson SA
   6  * Author: Ulf Hansson <ulf.hansson@linaro.org>
   7  */
   8 
   9 #include <linux/clk-provider.h>
  10 #include <linux/mfd/abx500/ab8500-sysctrl.h>
  11 #include <linux/device.h>
  12 #include <linux/slab.h>
  13 #include <linux/delay.h>
  14 #include <linux/io.h>
  15 #include <linux/err.h>
  16 #include "clk.h"
  17 
  18 #define SYSCTRL_MAX_NUM_PARENTS 4
  19 
  20 #define to_clk_sysctrl(_hw) container_of(_hw, struct clk_sysctrl, hw)
  21 
  22 struct clk_sysctrl {
  23         struct clk_hw hw;
  24         struct device *dev;
  25         u8 parent_index;
  26         u16 reg_sel[SYSCTRL_MAX_NUM_PARENTS];
  27         u8 reg_mask[SYSCTRL_MAX_NUM_PARENTS];
  28         u8 reg_bits[SYSCTRL_MAX_NUM_PARENTS];
  29         unsigned long rate;
  30         unsigned long enable_delay_us;
  31 };
  32 
  33 /* Sysctrl clock operations. */
  34 
  35 static int clk_sysctrl_prepare(struct clk_hw *hw)
  36 {
  37         int ret;
  38         struct clk_sysctrl *clk = to_clk_sysctrl(hw);
  39 
  40         ret = ab8500_sysctrl_write(clk->reg_sel[0], clk->reg_mask[0],
  41                                 clk->reg_bits[0]);
  42 
  43         if (!ret && clk->enable_delay_us)
  44                 usleep_range(clk->enable_delay_us, clk->enable_delay_us +
  45                              (clk->enable_delay_us >> 2));
  46 
  47         return ret;
  48 }
  49 
  50 static void clk_sysctrl_unprepare(struct clk_hw *hw)
  51 {
  52         struct clk_sysctrl *clk = to_clk_sysctrl(hw);
  53         if (ab8500_sysctrl_clear(clk->reg_sel[0], clk->reg_mask[0]))
  54                 dev_err(clk->dev, "clk_sysctrl: %s fail to clear %s.\n",
  55                         __func__, clk_hw_get_name(hw));
  56 }
  57 
  58 static unsigned long clk_sysctrl_recalc_rate(struct clk_hw *hw,
  59                                         unsigned long parent_rate)
  60 {
  61         struct clk_sysctrl *clk = to_clk_sysctrl(hw);
  62         return clk->rate;
  63 }
  64 
  65 static int clk_sysctrl_set_parent(struct clk_hw *hw, u8 index)
  66 {
  67         struct clk_sysctrl *clk = to_clk_sysctrl(hw);
  68         u8 old_index = clk->parent_index;
  69         int ret = 0;
  70 
  71         if (clk->reg_sel[old_index]) {
  72                 ret = ab8500_sysctrl_clear(clk->reg_sel[old_index],
  73                                         clk->reg_mask[old_index]);
  74                 if (ret)
  75                         return ret;
  76         }
  77 
  78         if (clk->reg_sel[index]) {
  79                 ret = ab8500_sysctrl_write(clk->reg_sel[index],
  80                                         clk->reg_mask[index],
  81                                         clk->reg_bits[index]);
  82                 if (ret) {
  83                         if (clk->reg_sel[old_index])
  84                                 ab8500_sysctrl_write(clk->reg_sel[old_index],
  85                                                 clk->reg_mask[old_index],
  86                                                 clk->reg_bits[old_index]);
  87                         return ret;
  88                 }
  89         }
  90         clk->parent_index = index;
  91 
  92         return ret;
  93 }
  94 
  95 static u8 clk_sysctrl_get_parent(struct clk_hw *hw)
  96 {
  97         struct clk_sysctrl *clk = to_clk_sysctrl(hw);
  98         return clk->parent_index;
  99 }
 100 
 101 static const struct clk_ops clk_sysctrl_gate_ops = {
 102         .prepare = clk_sysctrl_prepare,
 103         .unprepare = clk_sysctrl_unprepare,
 104 };
 105 
 106 static const struct clk_ops clk_sysctrl_gate_fixed_rate_ops = {
 107         .prepare = clk_sysctrl_prepare,
 108         .unprepare = clk_sysctrl_unprepare,
 109         .recalc_rate = clk_sysctrl_recalc_rate,
 110 };
 111 
 112 static const struct clk_ops clk_sysctrl_set_parent_ops = {
 113         .set_parent = clk_sysctrl_set_parent,
 114         .get_parent = clk_sysctrl_get_parent,
 115 };
 116 
 117 static struct clk *clk_reg_sysctrl(struct device *dev,
 118                                 const char *name,
 119                                 const char **parent_names,
 120                                 u8 num_parents,
 121                                 u16 *reg_sel,
 122                                 u8 *reg_mask,
 123                                 u8 *reg_bits,
 124                                 unsigned long rate,
 125                                 unsigned long enable_delay_us,
 126                                 unsigned long flags,
 127                                 const struct clk_ops *clk_sysctrl_ops)
 128 {
 129         struct clk_sysctrl *clk;
 130         struct clk_init_data clk_sysctrl_init;
 131         struct clk *clk_reg;
 132         int i;
 133 
 134         if (!dev)
 135                 return ERR_PTR(-EINVAL);
 136 
 137         if (!name || (num_parents > SYSCTRL_MAX_NUM_PARENTS)) {
 138                 dev_err(dev, "clk_sysctrl: invalid arguments passed\n");
 139                 return ERR_PTR(-EINVAL);
 140         }
 141 
 142         clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
 143         if (!clk)
 144                 return ERR_PTR(-ENOMEM);
 145 
 146         /* set main clock registers */
 147         clk->reg_sel[0] = reg_sel[0];
 148         clk->reg_bits[0] = reg_bits[0];
 149         clk->reg_mask[0] = reg_mask[0];
 150 
 151         /* handle clocks with more than one parent */
 152         for (i = 1; i < num_parents; i++) {
 153                 clk->reg_sel[i] = reg_sel[i];
 154                 clk->reg_bits[i] = reg_bits[i];
 155                 clk->reg_mask[i] = reg_mask[i];
 156         }
 157 
 158         clk->parent_index = 0;
 159         clk->rate = rate;
 160         clk->enable_delay_us = enable_delay_us;
 161         clk->dev = dev;
 162 
 163         clk_sysctrl_init.name = name;
 164         clk_sysctrl_init.ops = clk_sysctrl_ops;
 165         clk_sysctrl_init.flags = flags;
 166         clk_sysctrl_init.parent_names = parent_names;
 167         clk_sysctrl_init.num_parents = num_parents;
 168         clk->hw.init = &clk_sysctrl_init;
 169 
 170         clk_reg = devm_clk_register(clk->dev, &clk->hw);
 171         if (IS_ERR(clk_reg))
 172                 dev_err(dev, "clk_sysctrl: clk_register failed\n");
 173 
 174         return clk_reg;
 175 }
 176 
 177 struct clk *clk_reg_sysctrl_gate(struct device *dev,
 178                                 const char *name,
 179                                 const char *parent_name,
 180                                 u16 reg_sel,
 181                                 u8 reg_mask,
 182                                 u8 reg_bits,
 183                                 unsigned long enable_delay_us,
 184                                 unsigned long flags)
 185 {
 186         const char **parent_names = (parent_name ? &parent_name : NULL);
 187         u8 num_parents = (parent_name ? 1 : 0);
 188 
 189         return clk_reg_sysctrl(dev, name, parent_names, num_parents,
 190                         &reg_sel, &reg_mask, &reg_bits, 0, enable_delay_us,
 191                         flags, &clk_sysctrl_gate_ops);
 192 }
 193 
 194 struct clk *clk_reg_sysctrl_gate_fixed_rate(struct device *dev,
 195                                         const char *name,
 196                                         const char *parent_name,
 197                                         u16 reg_sel,
 198                                         u8 reg_mask,
 199                                         u8 reg_bits,
 200                                         unsigned long rate,
 201                                         unsigned long enable_delay_us,
 202                                         unsigned long flags)
 203 {
 204         const char **parent_names = (parent_name ? &parent_name : NULL);
 205         u8 num_parents = (parent_name ? 1 : 0);
 206 
 207         return clk_reg_sysctrl(dev, name, parent_names, num_parents,
 208                         &reg_sel, &reg_mask, &reg_bits,
 209                         rate, enable_delay_us, flags,
 210                         &clk_sysctrl_gate_fixed_rate_ops);
 211 }
 212 
 213 struct clk *clk_reg_sysctrl_set_parent(struct device *dev,
 214                                 const char *name,
 215                                 const char **parent_names,
 216                                 u8 num_parents,
 217                                 u16 *reg_sel,
 218                                 u8 *reg_mask,
 219                                 u8 *reg_bits,
 220                                 unsigned long flags)
 221 {
 222         return clk_reg_sysctrl(dev, name, parent_names, num_parents,
 223                         reg_sel, reg_mask, reg_bits, 0, 0, flags,
 224                         &clk_sysctrl_set_parent_ops);
 225 }

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