linux/drivers/clk/zynq/pll.c
<<
>>
Prefs
   1/*
   2 * Zynq PLL driver
   3 *
   4 *  Copyright (C) 2013 Xilinx
   5 *
   6 *  Sören Brinkmann <soren.brinkmann@xilinx.com>
   7 *
   8 * This program is free software: you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License v2 as published by
  10 * the Free Software Foundation.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19 *
  20 */
  21#include <linux/clk/zynq.h>
  22#include <linux/clk-provider.h>
  23#include <linux/slab.h>
  24#include <linux/io.h>
  25
  26/**
  27 * struct zynq_pll
  28 * @hw:         Handle between common and hardware-specific interfaces
  29 * @pll_ctrl:   PLL control register
  30 * @pll_status: PLL status register
  31 * @lock:       Register lock
  32 * @lockbit:    Indicates the associated PLL_LOCKED bit in the PLL status
  33 *              register.
  34 */
  35struct zynq_pll {
  36        struct clk_hw   hw;
  37        void __iomem    *pll_ctrl;
  38        void __iomem    *pll_status;
  39        spinlock_t      *lock;
  40        u8              lockbit;
  41};
  42#define to_zynq_pll(_hw)        container_of(_hw, struct zynq_pll, hw)
  43
  44/* Register bitfield defines */
  45#define PLLCTRL_FBDIV_MASK      0x7f000
  46#define PLLCTRL_FBDIV_SHIFT     12
  47#define PLLCTRL_BPQUAL_MASK     (1 << 3)
  48#define PLLCTRL_PWRDWN_MASK     2
  49#define PLLCTRL_PWRDWN_SHIFT    1
  50#define PLLCTRL_RESET_MASK      1
  51#define PLLCTRL_RESET_SHIFT     0
  52
  53#define PLL_FBDIV_MIN   13
  54#define PLL_FBDIV_MAX   66
  55
  56/**
  57 * zynq_pll_round_rate() - Round a clock frequency
  58 * @hw:         Handle between common and hardware-specific interfaces
  59 * @rate:       Desired clock frequency
  60 * @prate:      Clock frequency of parent clock
  61 * Returns frequency closest to @rate the hardware can generate.
  62 */
  63static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate,
  64                unsigned long *prate)
  65{
  66        u32 fbdiv;
  67
  68        fbdiv = DIV_ROUND_CLOSEST(rate, *prate);
  69        if (fbdiv < PLL_FBDIV_MIN)
  70                fbdiv = PLL_FBDIV_MIN;
  71        else if (fbdiv > PLL_FBDIV_MAX)
  72                fbdiv = PLL_FBDIV_MAX;
  73
  74        return *prate * fbdiv;
  75}
  76
  77/**
  78 * zynq_pll_recalc_rate() - Recalculate clock frequency
  79 * @hw:                 Handle between common and hardware-specific interfaces
  80 * @parent_rate:        Clock frequency of parent clock
  81 * Returns current clock frequency.
  82 */
  83static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
  84                unsigned long parent_rate)
  85{
  86        struct zynq_pll *clk = to_zynq_pll(hw);
  87        u32 fbdiv;
  88
  89        /*
  90         * makes probably sense to redundantly save fbdiv in the struct
  91         * zynq_pll to save the IO access.
  92         */
  93        fbdiv = (clk_readl(clk->pll_ctrl) & PLLCTRL_FBDIV_MASK) >>
  94                        PLLCTRL_FBDIV_SHIFT;
  95
  96        return parent_rate * fbdiv;
  97}
  98
  99/**
 100 * zynq_pll_is_enabled - Check if a clock is enabled
 101 * @hw:         Handle between common and hardware-specific interfaces
 102 * Returns 1 if the clock is enabled, 0 otherwise.
 103 *
 104 * Not sure this is a good idea, but since disabled means bypassed for
 105 * this clock implementation we say we are always enabled.
 106 */
 107static int zynq_pll_is_enabled(struct clk_hw *hw)
 108{
 109        unsigned long flags = 0;
 110        u32 reg;
 111        struct zynq_pll *clk = to_zynq_pll(hw);
 112
 113        spin_lock_irqsave(clk->lock, flags);
 114
 115        reg = clk_readl(clk->pll_ctrl);
 116
 117        spin_unlock_irqrestore(clk->lock, flags);
 118
 119        return !(reg & (PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK));
 120}
 121
 122/**
 123 * zynq_pll_enable - Enable clock
 124 * @hw:         Handle between common and hardware-specific interfaces
 125 * Returns 0 on success
 126 */
 127static int zynq_pll_enable(struct clk_hw *hw)
 128{
 129        unsigned long flags = 0;
 130        u32 reg;
 131        struct zynq_pll *clk = to_zynq_pll(hw);
 132
 133        if (zynq_pll_is_enabled(hw))
 134                return 0;
 135
 136        pr_info("PLL: enable\n");
 137
 138        /* Power up PLL and wait for lock */
 139        spin_lock_irqsave(clk->lock, flags);
 140
 141        reg = clk_readl(clk->pll_ctrl);
 142        reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK);
 143        clk_writel(reg, clk->pll_ctrl);
 144        while (!(clk_readl(clk->pll_status) & (1 << clk->lockbit)))
 145                ;
 146
 147        spin_unlock_irqrestore(clk->lock, flags);
 148
 149        return 0;
 150}
 151
 152/**
 153 * zynq_pll_disable - Disable clock
 154 * @hw:         Handle between common and hardware-specific interfaces
 155 * Returns 0 on success
 156 */
 157static void zynq_pll_disable(struct clk_hw *hw)
 158{
 159        unsigned long flags = 0;
 160        u32 reg;
 161        struct zynq_pll *clk = to_zynq_pll(hw);
 162
 163        if (!zynq_pll_is_enabled(hw))
 164                return;
 165
 166        pr_info("PLL: shutdown\n");
 167
 168        /* shut down PLL */
 169        spin_lock_irqsave(clk->lock, flags);
 170
 171        reg = clk_readl(clk->pll_ctrl);
 172        reg |= PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK;
 173        clk_writel(reg, clk->pll_ctrl);
 174
 175        spin_unlock_irqrestore(clk->lock, flags);
 176}
 177
 178static const struct clk_ops zynq_pll_ops = {
 179        .enable = zynq_pll_enable,
 180        .disable = zynq_pll_disable,
 181        .is_enabled = zynq_pll_is_enabled,
 182        .round_rate = zynq_pll_round_rate,
 183        .recalc_rate = zynq_pll_recalc_rate
 184};
 185
 186/**
 187 * clk_register_zynq_pll() - Register PLL with the clock framework
 188 * @name        PLL name
 189 * @parent      Parent clock name
 190 * @pll_ctrl    Pointer to PLL control register
 191 * @pll_status  Pointer to PLL status register
 192 * @lock_index  Bit index to this PLL's lock status bit in @pll_status
 193 * @lock        Register lock
 194 * Returns handle to the registered clock.
 195 */
 196struct clk *clk_register_zynq_pll(const char *name, const char *parent,
 197                void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index,
 198                spinlock_t *lock)
 199{
 200        struct zynq_pll *pll;
 201        struct clk *clk;
 202        u32 reg;
 203        const char *parent_arr[1] = {parent};
 204        unsigned long flags = 0;
 205        struct clk_init_data initd = {
 206                .name = name,
 207                .parent_names = parent_arr,
 208                .ops = &zynq_pll_ops,
 209                .num_parents = 1,
 210                .flags = 0
 211        };
 212
 213        pll = kmalloc(sizeof(*pll), GFP_KERNEL);
 214        if (!pll)
 215                return ERR_PTR(-ENOMEM);
 216
 217        /* Populate the struct */
 218        pll->hw.init = &initd;
 219        pll->pll_ctrl = pll_ctrl;
 220        pll->pll_status = pll_status;
 221        pll->lockbit = lock_index;
 222        pll->lock = lock;
 223
 224        spin_lock_irqsave(pll->lock, flags);
 225
 226        reg = clk_readl(pll->pll_ctrl);
 227        reg &= ~PLLCTRL_BPQUAL_MASK;
 228        clk_writel(reg, pll->pll_ctrl);
 229
 230        spin_unlock_irqrestore(pll->lock, flags);
 231
 232        clk = clk_register(NULL, &pll->hw);
 233        if (WARN_ON(IS_ERR(clk)))
 234                goto free_pll;
 235
 236        return clk;
 237
 238free_pll:
 239        kfree(pll);
 240
 241        return clk;
 242}
 243