root/drivers/clk/sunxi-ng/ccu_frac.c

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

DEFINITIONS

This source file includes following definitions.
  1. ccu_frac_helper_is_enabled
  2. ccu_frac_helper_enable
  3. ccu_frac_helper_disable
  4. ccu_frac_helper_has_rate
  5. ccu_frac_helper_read_rate
  6. ccu_frac_helper_set_rate

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2016 Maxime Ripard
   4  * Maxime Ripard <maxime.ripard@free-electrons.com>
   5  */
   6 
   7 #include <linux/clk-provider.h>
   8 #include <linux/io.h>
   9 #include <linux/spinlock.h>
  10 
  11 #include "ccu_frac.h"
  12 
  13 bool ccu_frac_helper_is_enabled(struct ccu_common *common,
  14                                 struct ccu_frac_internal *cf)
  15 {
  16         if (!(common->features & CCU_FEATURE_FRACTIONAL))
  17                 return false;
  18 
  19         return !(readl(common->base + common->reg) & cf->enable);
  20 }
  21 
  22 void ccu_frac_helper_enable(struct ccu_common *common,
  23                             struct ccu_frac_internal *cf)
  24 {
  25         unsigned long flags;
  26         u32 reg;
  27 
  28         if (!(common->features & CCU_FEATURE_FRACTIONAL))
  29                 return;
  30 
  31         spin_lock_irqsave(common->lock, flags);
  32         reg = readl(common->base + common->reg);
  33         writel(reg & ~cf->enable, common->base + common->reg);
  34         spin_unlock_irqrestore(common->lock, flags);
  35 }
  36 
  37 void ccu_frac_helper_disable(struct ccu_common *common,
  38                              struct ccu_frac_internal *cf)
  39 {
  40         unsigned long flags;
  41         u32 reg;
  42 
  43         if (!(common->features & CCU_FEATURE_FRACTIONAL))
  44                 return;
  45 
  46         spin_lock_irqsave(common->lock, flags);
  47         reg = readl(common->base + common->reg);
  48         writel(reg | cf->enable, common->base + common->reg);
  49         spin_unlock_irqrestore(common->lock, flags);
  50 }
  51 
  52 bool ccu_frac_helper_has_rate(struct ccu_common *common,
  53                               struct ccu_frac_internal *cf,
  54                               unsigned long rate)
  55 {
  56         if (!(common->features & CCU_FEATURE_FRACTIONAL))
  57                 return false;
  58 
  59         return (cf->rates[0] == rate) || (cf->rates[1] == rate);
  60 }
  61 
  62 unsigned long ccu_frac_helper_read_rate(struct ccu_common *common,
  63                                         struct ccu_frac_internal *cf)
  64 {
  65         u32 reg;
  66 
  67         pr_debug("%s: Read fractional\n", clk_hw_get_name(&common->hw));
  68 
  69         if (!(common->features & CCU_FEATURE_FRACTIONAL))
  70                 return 0;
  71 
  72         pr_debug("%s: clock is fractional (rates %lu and %lu)\n",
  73                  clk_hw_get_name(&common->hw), cf->rates[0], cf->rates[1]);
  74 
  75         reg = readl(common->base + common->reg);
  76 
  77         pr_debug("%s: clock reg is 0x%x (select is 0x%x)\n",
  78                  clk_hw_get_name(&common->hw), reg, cf->select);
  79 
  80         return (reg & cf->select) ? cf->rates[1] : cf->rates[0];
  81 }
  82 
  83 int ccu_frac_helper_set_rate(struct ccu_common *common,
  84                              struct ccu_frac_internal *cf,
  85                              unsigned long rate, u32 lock)
  86 {
  87         unsigned long flags;
  88         u32 reg, sel;
  89 
  90         if (!(common->features & CCU_FEATURE_FRACTIONAL))
  91                 return -EINVAL;
  92 
  93         if (cf->rates[0] == rate)
  94                 sel = 0;
  95         else if (cf->rates[1] == rate)
  96                 sel = cf->select;
  97         else
  98                 return -EINVAL;
  99 
 100         spin_lock_irqsave(common->lock, flags);
 101         reg = readl(common->base + common->reg);
 102         reg &= ~cf->select;
 103         writel(reg | sel, common->base + common->reg);
 104         spin_unlock_irqrestore(common->lock, flags);
 105 
 106         ccu_helper_wait_for_lock(common, lock);
 107 
 108         return 0;
 109 }

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