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